include/msvcrt: Define more CPU control word flags.
[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     /* Test how the viewport affects clears */
494     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
495     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
496     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
497     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
498
499     vp.X = 160;
500     vp.Y = 120;
501     vp.Width = 160;
502     vp.Height = 120;
503     vp.MinZ = 0.0;
504     vp.MaxZ = 1.0;
505     hr = IDirect3DDevice9_SetViewport(device, &vp);
506     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
507     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
508     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
509
510     vp.X = 320;
511     vp.Y = 240;
512     vp.Width = 320;
513     vp.Height = 240;
514     vp.MinZ = 0.0;
515     vp.MaxZ = 1.0;
516     hr = IDirect3DDevice9_SetViewport(device, &vp);
517     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
518     rect[0].x1 = 160;
519     rect[0].y1 = 120;
520     rect[0].x2 = 480;
521     rect[0].y2 = 360;
522     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
523     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
524
525     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
526     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
527
528     color = getPixelColor(device, 158, 118);
529     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
530     color = getPixelColor(device, 162, 118);
531     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
532     color = getPixelColor(device, 158, 122);
533     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
534     color = getPixelColor(device, 162, 122);
535     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
536
537     color = getPixelColor(device, 318, 238);
538     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
539     color = getPixelColor(device, 322, 238);
540     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
541     color = getPixelColor(device, 318, 242);
542     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
543     color = getPixelColor(device, 322, 242);
544     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
545
546     color = getPixelColor(device, 478, 358);
547     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
548     color = getPixelColor(device, 482, 358);
549     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
550     color = getPixelColor(device, 478, 362);
551     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
552     color = getPixelColor(device, 482, 362);
553     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
554
555     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
556
557     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
558     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559
560     scissor.left = 160;
561     scissor.right = 480;
562     scissor.top = 120;
563     scissor.bottom = 360;
564     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
565     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
566     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
567     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
568
569     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
570     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
571     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
572     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
573
574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
575     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576
577     color = getPixelColor(device, 158, 118);
578     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
579     color = getPixelColor(device, 162, 118);
580     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
581     color = getPixelColor(device, 158, 122);
582     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
583     color = getPixelColor(device, 162, 122);
584     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
585
586     color = getPixelColor(device, 158, 358);
587     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
588     color = getPixelColor(device, 162, 358);
589     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
590     color = getPixelColor(device, 158, 358);
591     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
592     color = getPixelColor(device, 162, 362);
593     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
594
595     color = getPixelColor(device, 478, 118);
596     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
597     color = getPixelColor(device, 478, 122);
598     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
599     color = getPixelColor(device, 482, 122);
600     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
601     color = getPixelColor(device, 482, 358);
602     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
603
604     color = getPixelColor(device, 478, 358);
605     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
606     color = getPixelColor(device, 478, 362);
607     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
608     color = getPixelColor(device, 482, 358);
609     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
610     color = getPixelColor(device, 482, 362);
611     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
612
613     color = getPixelColor(device, 318, 238);
614     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
615     color = getPixelColor(device, 318, 242);
616     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
617     color = getPixelColor(device, 322, 238);
618     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
619     color = getPixelColor(device, 322, 242);
620     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
621
622     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
623
624     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
625     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
627     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
628
629     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
630     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
631
632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
633     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
634
635     /* Colorwriteenable does not affect the clear */
636     color = getPixelColor(device, 320, 240);
637     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
638
639     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
640 }
641
642 static void color_fill_test(IDirect3DDevice9 *device)
643 {
644     HRESULT hr;
645     IDirect3DSurface9 *backbuffer = NULL;
646     IDirect3DSurface9 *rt_surface = NULL;
647     IDirect3DSurface9 *offscreen_surface = NULL;
648     DWORD fill_color, color;
649
650     /* Test ColorFill on a the backbuffer (should pass) */
651     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
652     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
653     if(backbuffer)
654     {
655         fill_color = 0x112233;
656         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
657
658         color = getPixelColor(device, 0, 0);
659         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
660
661         IDirect3DSurface9_Release(backbuffer);
662     }
663
664     /* Test ColorFill on a render target surface (should pass) */
665     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
666     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
667     if(rt_surface)
668     {
669         fill_color = 0x445566;
670         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
671
672         color = getPixelColorFromSurface(rt_surface, 0, 0);
673         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
674
675         IDirect3DSurface9_Release(rt_surface);
676     }
677
678     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
679     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
680             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
681     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
682     if(offscreen_surface)
683     {
684         fill_color = 0x778899;
685         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
686
687         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
688         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
689
690         IDirect3DSurface9_Release(offscreen_surface);
691     }
692
693     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
694     offscreen_surface = NULL;
695     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
697     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698     if(offscreen_surface)
699     {
700         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
701         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
702
703         IDirect3DSurface9_Release(offscreen_surface);
704     }
705 }
706
707 typedef struct {
708     float in[4];
709     DWORD out;
710 } test_data_t;
711
712 /*
713  *  c7      mova    ARGB            mov     ARGB
714  * -2.4     -2      0x00ffff00      -3      0x00ff0000
715  * -1.6     -2      0x00ffff00      -2      0x00ffff00
716  * -0.4      0      0x0000ffff      -1      0x0000ff00
717  *  0.4      0      0x0000ffff       0      0x0000ffff
718  *  1.6      2      0x00ff00ff       1      0x000000ff
719  *  2.4      2      0x00ff00ff       2      0x00ff00ff
720  */
721 static void test_mova(IDirect3DDevice9 *device)
722 {
723     static const DWORD mova_test[] = {
724         0xfffe0200,                                                             /* vs_2_0                       */
725         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
726         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
727         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
728         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
729         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
730         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
731         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
732         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
733         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
734         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
735         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
736         0x0000ffff                                                              /* END                          */
737     };
738     static const DWORD mov_test[] = {
739         0xfffe0101,                                                             /* vs_1_1                       */
740         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
741         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
742         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
743         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
744         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
745         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
746         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
747         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
748         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
749         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
750         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
751         0x0000ffff                                                              /* END                          */
752     };
753
754     static const test_data_t test_data[2][6] = {
755         {
756             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
757             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
758             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
759             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
760             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
761             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
762         },
763         {
764             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
766             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
768             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
769             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
770         }
771     };
772
773     static const float quad[][3] = {
774         {-1.0f, -1.0f, 0.0f},
775         {-1.0f,  1.0f, 0.0f},
776         { 1.0f, -1.0f, 0.0f},
777         { 1.0f,  1.0f, 0.0f},
778     };
779
780     static const D3DVERTEXELEMENT9 decl_elements[] = {
781         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
782         D3DDECL_END()
783     };
784
785     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
786     IDirect3DVertexShader9 *mova_shader = NULL;
787     IDirect3DVertexShader9 *mov_shader = NULL;
788     HRESULT hr;
789     UINT i, j;
790
791     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
792     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
793     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
794     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
795     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
796     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
797     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
798     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
799
800     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
801     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
802     for(j = 0; j < 2; ++j)
803     {
804         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
805         {
806             DWORD color;
807
808             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
809             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
810
811             hr = IDirect3DDevice9_BeginScene(device);
812             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
813
814             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
815             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
816
817             hr = IDirect3DDevice9_EndScene(device);
818             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
819
820             color = getPixelColor(device, 320, 240);
821             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
822                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
823
824             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
825             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
826
827             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
828             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
829         }
830         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
831         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
832     }
833
834     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
835     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836
837     IDirect3DVertexDeclaration9_Release(vertex_declaration);
838     IDirect3DVertexShader9_Release(mova_shader);
839     IDirect3DVertexShader9_Release(mov_shader);
840 }
841
842 struct sVertex {
843     float x, y, z;
844     DWORD diffuse;
845     DWORD specular;
846 };
847
848 struct sVertexT {
849     float x, y, z, rhw;
850     DWORD diffuse;
851     DWORD specular;
852 };
853
854 static void fog_test(IDirect3DDevice9 *device)
855 {
856     HRESULT hr;
857     D3DCOLOR color;
858     float start = 0.0f, end = 1.0f;
859     D3DCAPS9 caps;
860     int i;
861
862     /* Gets full z based fog with linear fog, no fog with specular color */
863     struct sVertex unstransformed_1[] = {
864         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
865         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
866         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
867         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
868     };
869     /* Ok, I am too lazy to deal with transform matrices */
870     struct sVertex unstransformed_2[] = {
871         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
872         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
873         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
874         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
875     };
876     /* Untransformed ones. Give them a different diffuse color to make the test look
877      * nicer. It also makes making sure that they are drawn correctly easier.
878      */
879     struct sVertexT transformed_1[] = {
880         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
881         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
882         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
883         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
884     };
885     struct sVertexT transformed_2[] = {
886         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
887         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
888         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
889         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
890     };
891     struct vertex rev_fog_quads[] = {
892        {-1.0,   -1.0,   0.1,    0x000000ff},
893        {-1.0,    0.0,   0.1,    0x000000ff},
894        { 0.0,    0.0,   0.1,    0x000000ff},
895        { 0.0,   -1.0,   0.1,    0x000000ff},
896
897        { 0.0,   -1.0,   0.9,    0x000000ff},
898        { 0.0,    0.0,   0.9,    0x000000ff},
899        { 1.0,    0.0,   0.9,    0x000000ff},
900        { 1.0,   -1.0,   0.9,    0x000000ff},
901
902        { 0.0,    0.0,   0.4,    0x000000ff},
903        { 0.0,    1.0,   0.4,    0x000000ff},
904        { 1.0,    1.0,   0.4,    0x000000ff},
905        { 1.0,    0.0,   0.4,    0x000000ff},
906
907        {-1.0,    0.0,   0.7,    0x000000ff},
908        {-1.0,    1.0,   0.7,    0x000000ff},
909        { 0.0,    1.0,   0.7,    0x000000ff},
910        { 0.0,    0.0,   0.7,    0x000000ff},
911     };
912     WORD Indices[] = {0, 1, 2, 2, 3, 0};
913
914     memset(&caps, 0, sizeof(caps));
915     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
916     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
917     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
918     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
919
920     /* Setup initial states: No lighting, fog on, fog color */
921     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
922     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
923     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
924     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
925     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
926     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
927
928     /* First test: Both table fog and vertex fog off */
929     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
930     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
931     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
932     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
933
934     /* Start = 0, end = 1. Should be default, but set them */
935     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
936     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
937     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
938     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
939
940     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
941     {
942         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
943         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
944         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
945         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
946                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
947                                                      sizeof(unstransformed_1[0]));
948         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
949
950         /* That makes it use the Z value */
951         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
952         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
953         /* Untransformed, vertex fog != none (or table fog != none):
954          * Use the Z value as input into the equation
955          */
956         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
957                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
958                                                      sizeof(unstransformed_1[0]));
959         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
960
961         /* transformed verts */
962         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
963         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
964         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
965         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
966                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
967                                                      sizeof(transformed_1[0]));
968         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
969
970         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
971         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
972         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
973          * equation
974          */
975         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
976                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
977                                                      sizeof(transformed_2[0]));
978         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
979
980         hr = IDirect3DDevice9_EndScene(device);
981         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
982     }
983     else
984     {
985         ok(FALSE, "BeginScene failed\n");
986     }
987
988     color = getPixelColor(device, 160, 360);
989     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
990     color = getPixelColor(device, 160, 120);
991     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
992     color = getPixelColor(device, 480, 120);
993     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
994     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
995     {
996         color = getPixelColor(device, 480, 360);
997         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
998     }
999     else
1000     {
1001         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1002          * The settings above result in no fogging with vertex fog
1003          */
1004         color = getPixelColor(device, 480, 120);
1005         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1006         trace("Info: Table fog not supported by this device\n");
1007     }
1008     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1009
1010     /* Now test the special case fogstart == fogend */
1011     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1012     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1013
1014     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1015     {
1016         start = 512;
1017         end = 512;
1018         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1019         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1020         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1021         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1022
1023         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1024         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1025         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1026         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1027         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1028         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1029
1030         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1031          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1032          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1033          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1034          * color and has fixed fogstart and fogend.
1035          */
1036         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1037                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1038                 sizeof(unstransformed_1[0]));
1039         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1040         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1041                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1042                 sizeof(unstransformed_1[0]));
1043         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1044
1045         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1046         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1047         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1048         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1049                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1050                 sizeof(transformed_1[0]));
1051         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1052
1053         hr = IDirect3DDevice9_EndScene(device);
1054         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1055     }
1056     else
1057     {
1058         ok(FALSE, "BeginScene failed\n");
1059     }
1060     color = getPixelColor(device, 160, 360);
1061     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1062     color = getPixelColor(device, 160, 120);
1063     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1064     color = getPixelColor(device, 480, 120);
1065     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1066     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1067
1068     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1069      * but without shaders it seems to work everywhere
1070      */
1071     end = 0.2;
1072     start = 0.8;
1073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1074     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1076     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1077     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1078     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1079
1080     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1081      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1082      * so skip this for now
1083      */
1084     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1085         const char *mode = (i ? "table" : "vertex");
1086         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1087         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1088         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1089         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1090         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1091         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1092         hr = IDirect3DDevice9_BeginScene(device);
1093         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1094         if(SUCCEEDED(hr)) {
1095             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1096                                 4,  5,  6,  6,  7, 4,
1097                                 8,  9, 10, 10, 11, 8,
1098                             12, 13, 14, 14, 15, 12};
1099
1100             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1101                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1102                     sizeof(rev_fog_quads[0]));
1103             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1104
1105             hr = IDirect3DDevice9_EndScene(device);
1106             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1107         }
1108         color = getPixelColor(device, 160, 360);
1109         ok(color_match(color, 0x0000ff00, 1),
1110                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1111
1112         color = getPixelColor(device, 160, 120);
1113         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1114                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1115
1116         color = getPixelColor(device, 480, 120);
1117         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1118                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1119
1120         color = getPixelColor(device, 480, 360);
1121         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1122
1123         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124
1125         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1126             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1127             break;
1128         }
1129     }
1130     /* Turn off the fog master switch to avoid confusing other tests */
1131     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1132     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1133     start = 0.0;
1134     end = 1.0;
1135     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1136     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1137     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1138     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1139     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1140     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1141     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1142     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1143 }
1144
1145 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1146  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1147  * regardless of the actual addressing mode set. The way this test works is
1148  * that we sample in one of the corners of the cubemap with filtering enabled,
1149  * and check the interpolated color. There are essentially two reasonable
1150  * things an implementation can do: Either pick one of the faces and
1151  * interpolate the edge texel with itself (i.e., clamp within the face), or
1152  * interpolate between the edge texels of the three involved faces. It should
1153  * never involve the border color or the other side (texcoord wrapping) of a
1154  * face in the interpolation. */
1155 static void test_cube_wrap(IDirect3DDevice9 *device)
1156 {
1157     static const float quad[][6] = {
1158         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1161         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1162     };
1163
1164     static const D3DVERTEXELEMENT9 decl_elements[] = {
1165         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1166         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1167         D3DDECL_END()
1168     };
1169
1170     static const struct {
1171         D3DTEXTUREADDRESS mode;
1172         const char *name;
1173     } address_modes[] = {
1174         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1175         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1176         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1177         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1178         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1179     };
1180
1181     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1182     IDirect3DCubeTexture9 *texture = NULL;
1183     IDirect3DSurface9 *surface = NULL;
1184     IDirect3DSurface9 *face_surface;
1185     D3DLOCKED_RECT locked_rect;
1186     HRESULT hr;
1187     UINT x;
1188     INT y, face;
1189
1190     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1191     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1192     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1193     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1194
1195     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1196             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1197     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1198
1199     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1200             D3DPOOL_DEFAULT, &texture, NULL);
1201     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1202
1203     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1204     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1205
1206     for (y = 0; y < 128; ++y)
1207     {
1208         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1209         for (x = 0; x < 64; ++x)
1210         {
1211             *ptr++ = 0xff0000ff;
1212         }
1213         for (x = 64; x < 128; ++x)
1214         {
1215             *ptr++ = 0xffff0000;
1216         }
1217     }
1218
1219     hr = IDirect3DSurface9_UnlockRect(surface);
1220     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1221
1222     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1223     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1224
1225     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1226     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1227
1228     IDirect3DSurface9_Release(face_surface);
1229
1230     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1231     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1232
1233     for (y = 0; y < 128; ++y)
1234     {
1235         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1236         for (x = 0; x < 64; ++x)
1237         {
1238             *ptr++ = 0xffff0000;
1239         }
1240         for (x = 64; x < 128; ++x)
1241         {
1242             *ptr++ = 0xff0000ff;
1243         }
1244     }
1245
1246     hr = IDirect3DSurface9_UnlockRect(surface);
1247     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1248
1249     /* Create cube faces */
1250     for (face = 1; face < 6; ++face)
1251     {
1252         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1253         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1254
1255         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1256         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1257
1258         IDirect3DSurface9_Release(face_surface);
1259     }
1260
1261     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1262     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1263
1264     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1265     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1266     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1267     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1268     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1269     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1270
1271     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1272     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1273
1274     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1275     {
1276         DWORD color;
1277
1278         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1279         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1280         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1281         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1282
1283         hr = IDirect3DDevice9_BeginScene(device);
1284         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1285
1286         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1287         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1288
1289         hr = IDirect3DDevice9_EndScene(device);
1290         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1291
1292         color = getPixelColor(device, 320, 240);
1293         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1294                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1295                 color, address_modes[x].name);
1296
1297         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1298         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1299
1300         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1301         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1302     }
1303
1304     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1305     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1306
1307     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1308     IDirect3DCubeTexture9_Release(texture);
1309     IDirect3DSurface9_Release(surface);
1310 }
1311
1312 static void offscreen_test(IDirect3DDevice9 *device)
1313 {
1314     HRESULT hr;
1315     IDirect3DTexture9 *offscreenTexture = NULL;
1316     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1317     DWORD color;
1318
1319     static const float quad[][5] = {
1320         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1321         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1322         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1323         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1324     };
1325
1326     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1327     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1328
1329     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1330     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1331     if(!offscreenTexture) {
1332         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1333         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1334         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1335         if(!offscreenTexture) {
1336             skip("Cannot create an offscreen render target\n");
1337             goto out;
1338         }
1339     }
1340
1341     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1342     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1343     if(!backbuffer) {
1344         goto out;
1345     }
1346
1347     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1348     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1349     if(!offscreen) {
1350         goto out;
1351     }
1352
1353     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1354     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1355
1356     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1357     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1358     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1359     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1360     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1361     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1362     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1363     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1364     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1365     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1366
1367     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1368         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1369         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1370         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1371         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1372
1373         /* Draw without textures - Should result in a white quad */
1374         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1375         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1376
1377         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1378         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1379         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1380         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1381
1382         /* This time with the texture */
1383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1384         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1385
1386         IDirect3DDevice9_EndScene(device);
1387     }
1388
1389     /* Center quad - should be white */
1390     color = getPixelColor(device, 320, 240);
1391     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1392     /* Some quad in the cleared part of the texture */
1393     color = getPixelColor(device, 170, 240);
1394     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1395     /* Part of the originally cleared back buffer */
1396     color = getPixelColor(device, 10, 10);
1397     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1398     if(0) {
1399         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1400          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1401          * the offscreen rendering mode this test would succeed or fail
1402          */
1403         color = getPixelColor(device, 10, 470);
1404         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1405     }
1406
1407     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1408
1409 out:
1410     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1411     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1412
1413     /* restore things */
1414     if(backbuffer) {
1415         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1416         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1417         IDirect3DSurface9_Release(backbuffer);
1418     }
1419     if(offscreenTexture) {
1420         IDirect3DTexture9_Release(offscreenTexture);
1421     }
1422     if(offscreen) {
1423         IDirect3DSurface9_Release(offscreen);
1424     }
1425 }
1426
1427 /* This test tests fog in combination with shaders.
1428  * What's tested: linear fog (vertex and table) with pixel shader
1429  *                linear table fog with non foggy vertex shader
1430  *                vertex fog with foggy vertex shader, non-linear
1431  *                fog with shader, non-linear fog with foggy shader,
1432  *                linear table fog with foggy shader
1433  */
1434 static void fog_with_shader_test(IDirect3DDevice9 *device)
1435 {
1436     HRESULT hr;
1437     DWORD color;
1438     union {
1439         float f;
1440         DWORD i;
1441     } start, end;
1442     unsigned int i, j;
1443
1444     /* basic vertex shader without fog computation ("non foggy") */
1445     static const DWORD vertex_shader_code1[] = {
1446         0xfffe0101,                                                             /* vs_1_1                       */
1447         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1448         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1449         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1450         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1451         0x0000ffff
1452     };
1453     /* basic vertex shader with reversed fog computation ("foggy") */
1454     static const DWORD vertex_shader_code2[] = {
1455         0xfffe0101,                                                             /* vs_1_1                        */
1456         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1457         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1458         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1459         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1460         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1461         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1462         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1463         0x0000ffff
1464     };
1465     /* basic pixel shader */
1466     static const DWORD pixel_shader_code[] = {
1467         0xffff0101,                                                             /* ps_1_1     */
1468         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1469         0x0000ffff
1470     };
1471
1472     static struct vertex quad[] = {
1473         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1474         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1475         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1476         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1477     };
1478
1479     static const D3DVERTEXELEMENT9 decl_elements[] = {
1480         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1481         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1482         D3DDECL_END()
1483     };
1484
1485     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1486     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1487     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1488
1489     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1490     static const struct test_data_t {
1491         int vshader;
1492         int pshader;
1493         D3DFOGMODE vfog;
1494         D3DFOGMODE tfog;
1495         unsigned int color[11];
1496     } test_data[] = {
1497         /* only pixel shader: */
1498         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1499         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1500         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1501         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1502         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1503         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1504         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1505         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1506         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1507         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1508         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1509         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1510         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1511         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1512         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1513
1514         /* vertex shader */
1515         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1516         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1517          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1518         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1519         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1520         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1521         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1522         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1523         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524
1525         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1526         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1527         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1528         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1529         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1530         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1531
1532         /* vertex shader and pixel shader */
1533         /* The next 4 tests would read the fog coord output, but it isn't available.
1534          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1535          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1536          * These tests should be disabled if some other hardware behaves differently
1537          */
1538         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1539         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1540         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1541         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1542         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1543         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1544         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1545         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1546         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1547         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1548         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1549         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1550
1551         /* These use the Z coordinate with linear table fog */
1552         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1553         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1554         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1555         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1556         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1557         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1558         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1559         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1560         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1561         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1562         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1563         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1564
1565         /* Non-linear table fog without fog coord */
1566         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1567         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1568         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1569         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1570         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1571         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1572
1573 #if 0  /* FIXME: these fail on GeForce 8500 */
1574         /* foggy vertex shader */
1575         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1576         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1577          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1578         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1579         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1580          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1581         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1582         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1583          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1584         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1585         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1586          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1587 #endif
1588
1589         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1590          * all using the fixed fog-coord linear fog
1591          */
1592         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1593         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1594          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1595         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1596         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1597          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1598         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1599         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1600          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1601         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1602         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1603          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604
1605         /* These use table fog. Here the shader-provided fog coordinate is
1606          * ignored and the z coordinate used instead
1607          */
1608         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1609         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1610         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1611         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1612         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1613         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1614         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1615         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1616         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1617     };
1618
1619     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1620     start.f=0.1f;
1621     end.f=0.9f;
1622
1623     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1624     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1625     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1626     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1627     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1628     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1629     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1630     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1631
1632     /* Setup initial states: No lighting, fog on, fog color */
1633     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1634     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1635     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1636     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1637     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1638     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1639     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1640     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1641
1642     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1643     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1644     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1645     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1646
1647     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1648     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1649     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1651     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1652
1653     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1654     {
1655         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1656         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1657         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1658         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1659         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1660         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1661         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1662         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1663
1664         for(j=0; j < 11; j++)
1665         {
1666             /* Don't use the whole zrange to prevent rounding errors */
1667             quad[0].z = 0.001f + (float)j / 10.02f;
1668             quad[1].z = 0.001f + (float)j / 10.02f;
1669             quad[2].z = 0.001f + (float)j / 10.02f;
1670             quad[3].z = 0.001f + (float)j / 10.02f;
1671
1672             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1673             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1674
1675             hr = IDirect3DDevice9_BeginScene(device);
1676             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1677
1678             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1679             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1680
1681             hr = IDirect3DDevice9_EndScene(device);
1682             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1683
1684             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1685             color = getPixelColor(device, 128, 240);
1686             ok(color_match(color, test_data[i].color[j], 13),
1687                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1688                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1689
1690             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1691         }
1692     }
1693
1694     /* reset states */
1695     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1696     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1697     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1698     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1699     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1700     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1701     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1702     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1703
1704     IDirect3DVertexShader9_Release(vertex_shader[1]);
1705     IDirect3DVertexShader9_Release(vertex_shader[2]);
1706     IDirect3DPixelShader9_Release(pixel_shader[1]);
1707     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1708 }
1709
1710 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1711     unsigned int i, x, y;
1712     HRESULT hr;
1713     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1714     D3DLOCKED_RECT locked_rect;
1715
1716     /* Generate the textures */
1717     for(i=0; i<2; i++)
1718     {
1719         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1720                                             D3DPOOL_MANAGED, &texture[i], NULL);
1721         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1722
1723         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1724         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1725         for (y = 0; y < 128; ++y)
1726         {
1727             if(i)
1728             { /* Set up black texture with 2x2 texel white spot in the middle */
1729                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1730                 for (x = 0; x < 128; ++x)
1731                 {
1732                     if(y>62 && y<66 && x>62 && x<66)
1733                         *ptr++ = 0xffffffff;
1734                     else
1735                         *ptr++ = 0xff000000;
1736                 }
1737             }
1738             else
1739             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1740                * (if multiplied with bumpenvmat)
1741               */
1742                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1743                 for (x = 0; x < 128; ++x)
1744                 {
1745                     if(abs(x-64)>abs(y-64))
1746                     {
1747                         if(x < 64)
1748                             *ptr++ = 0xc000;
1749                         else
1750                             *ptr++ = 0x4000;
1751                     }
1752                     else
1753                     {
1754                         if(y < 64)
1755                             *ptr++ = 0x0040;
1756                         else
1757                             *ptr++ = 0x00c0;
1758                     }
1759                 }
1760             }
1761         }
1762         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1763         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1764
1765         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1766         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1767
1768         /* Disable texture filtering */
1769         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1770         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1771         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1772         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1773
1774         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1775         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1776         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1777         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1778     }
1779 }
1780
1781 /* test the behavior of the texbem instruction
1782  * with normal 2D and projective 2D textures
1783  */
1784 static void texbem_test(IDirect3DDevice9 *device)
1785 {
1786     HRESULT hr;
1787     DWORD color;
1788     int i;
1789
1790     static const DWORD pixel_shader_code[] = {
1791         0xffff0101,                         /* ps_1_1*/
1792         0x00000042, 0xb00f0000,             /* tex t0*/
1793         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1794         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1795         0x0000ffff
1796     };
1797     static const DWORD double_texbem_code[] =  {
1798         0xffff0103,                                         /* ps_1_3           */
1799         0x00000042, 0xb00f0000,                             /* tex t0           */
1800         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1801         0x00000042, 0xb00f0002,                             /* tex t2           */
1802         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1803         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1804         0x0000ffff                                          /* end              */
1805     };
1806
1807
1808     static const float quad[][7] = {
1809         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1810         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1811         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1812         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1813     };
1814     static const float quad_proj[][9] = {
1815         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1816         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1817         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1818         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1819     };
1820
1821     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1822         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1823         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1824         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1825         D3DDECL_END()
1826     },{
1827         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1828         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1829         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1830         D3DDECL_END()
1831     } };
1832
1833     /* use asymmetric matrix to test loading */
1834     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1835
1836     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1837     IDirect3DPixelShader9       *pixel_shader       = NULL;
1838     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1839     D3DLOCKED_RECT locked_rect;
1840
1841     generate_bumpmap_textures(device);
1842
1843     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1844     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1845     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1846     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1847     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1848
1849     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1850     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1851
1852     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1853     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1854
1855     for(i=0; i<2; i++)
1856     {
1857         if(i)
1858         {
1859             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1860             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1861         }
1862
1863         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1864         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1865         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1866         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1867
1868         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1869         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1870         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1871         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1872
1873         hr = IDirect3DDevice9_BeginScene(device);
1874         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1875
1876         if(!i)
1877             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1878         else
1879             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1880         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1881
1882         hr = IDirect3DDevice9_EndScene(device);
1883         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1884
1885         color = getPixelColor(device, 320-32, 240);
1886         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1887         color = getPixelColor(device, 320+32, 240);
1888         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1889         color = getPixelColor(device, 320, 240-32);
1890         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1891         color = getPixelColor(device, 320, 240+32);
1892         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1893
1894         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1895         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1896
1897         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1898         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1899         IDirect3DPixelShader9_Release(pixel_shader);
1900
1901         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1902         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1903         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1904     }
1905
1906     /* clean up */
1907     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1908     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1909
1910     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1911     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1912
1913     for(i=0; i<2; i++)
1914     {
1915         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1916         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1917         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1918         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1919         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1920         IDirect3DTexture9_Release(texture);
1921     }
1922
1923     /* Test double texbem */
1924     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1925     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1926     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1927     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1928     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1929     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1930     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1931     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1932
1933     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1934     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1935     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1936     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1937
1938     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1939     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1940
1941     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1942     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1943     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1944     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1945     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1946     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1947
1948     {
1949         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1950 #define tex  0x00ff0000
1951 #define tex1 0x0000ff00
1952 #define origin 0x000000ff
1953         static const DWORD pixel_data[] = {
1954             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1958             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1959             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1961             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1962         };
1963 #undef tex1
1964 #undef tex2
1965 #undef origin
1966
1967         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1968         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1969         for(i = 0; i < 8; i++) {
1970             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1971         }
1972         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1973         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1974     }
1975
1976     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1977     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1978     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1979     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1980     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1981     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1982     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1983     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1984     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1985     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1986     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1987     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1988
1989     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1990     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1991     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1992     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1993     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1994     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1995     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1996     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1997     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1998     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1999
2000     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2001     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2002     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2003     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2004     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2005     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2006     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2007     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2008     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2009     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010
2011     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2012     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2013     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2014     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2015     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2016     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2017     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2018     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2019     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2020     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2021     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2022     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2023     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2025     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2026     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2027
2028     hr = IDirect3DDevice9_BeginScene(device);
2029     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2030     if(SUCCEEDED(hr)) {
2031         static const float double_quad[] = {
2032             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2033              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2034             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2035              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2036         };
2037
2038         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2039         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2040         hr = IDirect3DDevice9_EndScene(device);
2041         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2042     }
2043     color = getPixelColor(device, 320, 240);
2044     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2045
2046     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2047     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2048     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2049     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2050     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2051     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2052     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2053     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2054     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2055     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2056
2057     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2058     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2059
2060     IDirect3DPixelShader9_Release(pixel_shader);
2061     IDirect3DTexture9_Release(texture);
2062     IDirect3DTexture9_Release(texture1);
2063     IDirect3DTexture9_Release(texture2);
2064 }
2065
2066 static void z_range_test(IDirect3DDevice9 *device)
2067 {
2068     const struct vertex quad[] =
2069     {
2070         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2071         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2072         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2073         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2074     };
2075     const struct vertex quad2[] =
2076     {
2077         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2078         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2079         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2080         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2081     };
2082
2083     const struct tvertex quad3[] =
2084     {
2085         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2086         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2087         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2088         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2089     };
2090     const struct tvertex quad4[] =
2091     {
2092         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2093         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2094         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2095         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2096     };
2097     HRESULT hr;
2098     DWORD color;
2099     IDirect3DVertexShader9 *shader;
2100     IDirect3DVertexDeclaration9 *decl;
2101     D3DCAPS9 caps;
2102     const DWORD shader_code[] = {
2103         0xfffe0101,                                     /* vs_1_1           */
2104         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2105         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2106         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2107         0x0000ffff                                      /* end              */
2108     };
2109     static const D3DVERTEXELEMENT9 decl_elements[] = {
2110         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2111         D3DDECL_END()
2112     };
2113     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2114      * then call Present. Then clear the color buffer to make sure it has some defined content
2115      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2116      * by the depth value.
2117      */
2118     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2119     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2120     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2121     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2122     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2123     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2124
2125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2126     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2130     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2131     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2132     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2133     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2134     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2135
2136     hr = IDirect3DDevice9_BeginScene(device);
2137     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2138     if(hr == D3D_OK)
2139     {
2140         /* Test the untransformed vertex path */
2141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2142         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2143         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2144         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2145         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2146         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2147
2148         /* Test the transformed vertex path */
2149         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2150         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2151
2152         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2153         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2154         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2155         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2157         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2158
2159         hr = IDirect3DDevice9_EndScene(device);
2160         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2161     }
2162
2163     /* Do not test the exact corner pixels, but go pretty close to them */
2164
2165     /* Clipped because z > 1.0 */
2166     color = getPixelColor(device, 28, 238);
2167     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2168     color = getPixelColor(device, 28, 241);
2169     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2170
2171     /* Not clipped, > z buffer clear value(0.75) */
2172     color = getPixelColor(device, 31, 238);
2173     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2174     color = getPixelColor(device, 31, 241);
2175     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2176     color = getPixelColor(device, 100, 238);
2177     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2178     color = getPixelColor(device, 100, 241);
2179     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2180
2181     /* Not clipped, < z buffer clear value */
2182     color = getPixelColor(device, 104, 238);
2183     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2184     color = getPixelColor(device, 104, 241);
2185     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2186     color = getPixelColor(device, 318, 238);
2187     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2188     color = getPixelColor(device, 318, 241);
2189     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2190
2191     /* Clipped because z < 0.0 */
2192     color = getPixelColor(device, 321, 238);
2193     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2194     color = getPixelColor(device, 321, 241);
2195     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2196
2197     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2198     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2199
2200     /* Test the shader path */
2201     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2202     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2203         skip("Vertex shaders not supported\n");
2204         goto out;
2205     }
2206     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2207     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2208     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2209     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2210
2211     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2212
2213     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2214     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2215     IDirect3DDevice9_SetVertexShader(device, shader);
2216     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2217
2218     hr = IDirect3DDevice9_BeginScene(device);
2219     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2220     if(hr == D3D_OK)
2221     {
2222         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2223         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2224         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2225         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2226         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2227         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2228         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2229         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2230         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2231         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2232
2233         hr = IDirect3DDevice9_EndScene(device);
2234         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2235     }
2236
2237     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2238     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2239     IDirect3DDevice9_SetVertexShader(device, NULL);
2240     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2241
2242     IDirect3DVertexDeclaration9_Release(decl);
2243     IDirect3DVertexShader9_Release(shader);
2244
2245     /* Z < 1.0 */
2246     color = getPixelColor(device, 28, 238);
2247     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2248
2249     /* 1.0 < z < 0.75 */
2250     color = getPixelColor(device, 31, 238);
2251     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2252     color = getPixelColor(device, 100, 238);
2253     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2254
2255     /* 0.75 < z < 0.0 */
2256     color = getPixelColor(device, 104, 238);
2257     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2258     color = getPixelColor(device, 318, 238);
2259     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2260
2261     /* 0.0 < z */
2262     color = getPixelColor(device, 321, 238);
2263     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2264
2265     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2266     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2267
2268     out:
2269     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2270     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2271     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2272     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2273     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2274     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2275 }
2276
2277 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2278 {
2279     D3DSURFACE_DESC desc;
2280     D3DLOCKED_RECT l;
2281     HRESULT hr;
2282     unsigned int x, y;
2283     DWORD *mem;
2284
2285     memset(&desc, 0, sizeof(desc));
2286     memset(&l, 0, sizeof(l));
2287     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2288     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2289     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2290     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2291     if(FAILED(hr)) return;
2292
2293     for(y = 0; y < desc.Height; y++)
2294     {
2295         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2296         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2297         {
2298             mem[x] = color;
2299         }
2300     }
2301     hr = IDirect3DSurface9_UnlockRect(surface);
2302     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2303 }
2304
2305 /* This tests a variety of possible StretchRect() situations */
2306 static void stretchrect_test(IDirect3DDevice9 *device)
2307 {
2308     HRESULT hr;
2309     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2310     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2311     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2312     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2313     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2314     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2315     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2316     IDirect3DSurface9 *orig_rt = NULL;
2317     IDirect3DSurface9 *backbuffer = NULL;
2318     DWORD color;
2319
2320     RECT src_rect64 = {0, 0, 64, 64};
2321     RECT src_rect64_flipy = {0, 64, 64, 0};
2322     RECT dst_rect64 = {0, 0, 64, 64};
2323     RECT dst_rect64_flipy = {0, 64, 64, 0};
2324
2325     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2326     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2327     if(!orig_rt) {
2328         goto out;
2329     }
2330
2331     /* Create our temporary surfaces in system memory */
2332     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2333     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2334     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2335     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2336
2337     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2338     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2339     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2340     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2341     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2342     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2343     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2344
2345     /* Create render target surfaces */
2346     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2347     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2348     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2349     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2350     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2351     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2352     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2353     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2354
2355     /* Create render target textures */
2356     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2357     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2358     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2359     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2360     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2361     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2362     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2363     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2364     if (tex_rt32) {
2365         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2366         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2367     }
2368     if (tex_rt64) {
2369         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2370         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2371     }
2372     if (tex_rt_dest64) {
2373         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2374         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2375     }
2376     if (tex_rt_dest64) {
2377         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2378         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2379     }
2380
2381     /* Create regular textures in D3DPOOL_DEFAULT */
2382     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2383     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2384     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2385     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2386     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2387     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2388     if (tex32) {
2389         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2390         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2391     }
2392     if (tex64) {
2393         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2394         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2395     }
2396     if (tex_dest64) {
2397         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2398         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2399     }
2400
2401     /*********************************************************************
2402      * Tests for when the source parameter is an offscreen plain surface *
2403      *********************************************************************/
2404
2405     /* Fill the offscreen 64x64 surface with green */
2406     if (surf_offscreen64)
2407         fill_surface(surf_offscreen64, 0xff00ff00);
2408
2409     /* offscreenplain ==> offscreenplain, same size */
2410     if(surf_offscreen64 && surf_offscreen_dest64) {
2411         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2412         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2413
2414         if (hr == D3D_OK) {
2415             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2416             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2417         }
2418
2419         /* Blit without scaling */
2420         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2421         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2422
2423         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2424         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2425         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2426
2427         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2428         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2429         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2430     }
2431
2432     /* offscreenplain ==> rendertarget texture, same size */
2433     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2434         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2435         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2436
2437         /* We can't lock rendertarget textures, so copy to our temp surface first */
2438         if (hr == D3D_OK) {
2439             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2440             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2441         }
2442
2443         if (hr == D3D_OK) {
2444             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2445             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2446         }
2447
2448         /* Blit without scaling */
2449         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2450         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2451
2452         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2453         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2454         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2455
2456         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2457         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2458         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2459     }
2460
2461     /* offscreenplain ==> rendertarget surface, same size */
2462     if(surf_offscreen64 && surf_rt_dest64) {
2463         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2464         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2465
2466         if (hr == D3D_OK) {
2467             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2468             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2469         }
2470
2471         /* Blit without scaling */
2472         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2473         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2474
2475         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2476         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2477         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2478
2479         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2480         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2481         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2482     }
2483
2484     /* offscreenplain ==> texture, same size (should fail) */
2485     if(surf_offscreen64 && surf_tex_dest64) {
2486         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2487         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2488     }
2489
2490     /* Fill the smaller offscreen surface with red */
2491     fill_surface(surf_offscreen32, 0xffff0000);
2492
2493     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2494     if(surf_offscreen32 && surf_offscreen64) {
2495         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2496         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2497     }
2498
2499     /* offscreenplain ==> rendertarget texture, scaling */
2500     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2501         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2502         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2503
2504         /* We can't lock rendertarget textures, so copy to our temp surface first */
2505         if (hr == D3D_OK) {
2506             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2507             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2508         }
2509
2510         if (hr == D3D_OK) {
2511             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2512             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2513         }
2514     }
2515
2516     /* offscreenplain ==> rendertarget surface, scaling */
2517     if(surf_offscreen32 && surf_rt_dest64) {
2518         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2519         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2520
2521         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2522         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2523     }
2524
2525     /* offscreenplain ==> texture, scaling (should fail) */
2526     if(surf_offscreen32 && surf_tex_dest64) {
2527         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2528         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2529     }
2530
2531     /************************************************************
2532      * Tests for when the source parameter is a regular texture *
2533      ************************************************************/
2534
2535     /* Fill the surface of the regular texture with blue */
2536     if (surf_tex64 && surf_temp64) {
2537         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2538         fill_surface(surf_temp64, 0xff0000ff);
2539         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2540         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2541     }
2542
2543     /* texture ==> offscreenplain, same size */
2544     if(surf_tex64 && surf_offscreen64) {
2545         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2546         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2547     }
2548
2549     /* texture ==> rendertarget texture, same size */
2550     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2551         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2552         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2553
2554         /* We can't lock rendertarget textures, so copy to our temp surface first */
2555         if (hr == D3D_OK) {
2556             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2557             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2558         }
2559
2560         if (hr == D3D_OK) {
2561             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2562             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2563         }
2564
2565         /* Blit without scaling */
2566         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2567         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2568
2569         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2570         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2571         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2572
2573         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2574         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2575         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2576     }
2577
2578     /* texture ==> rendertarget surface, same size */
2579     if(surf_tex64 && surf_rt_dest64) {
2580         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2581         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2582
2583         if (hr == D3D_OK) {
2584             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2585             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2586         }
2587
2588         /* Blit without scaling */
2589         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2590         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2591
2592         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2593         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2594         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2595
2596         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2597         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2598         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2599     }
2600
2601     /* texture ==> texture, same size (should fail) */
2602     if(surf_tex64 && surf_tex_dest64) {
2603         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2604         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2605     }
2606
2607     /* Fill the surface of the smaller regular texture with red */
2608     if (surf_tex32 && surf_temp32) {
2609         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2610         fill_surface(surf_temp32, 0xffff0000);
2611         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2612         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2613     }
2614
2615     /* texture ==> offscreenplain, scaling (should fail) */
2616     if(surf_tex32 && surf_offscreen64) {
2617         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2618         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2619     }
2620
2621     /* texture ==> rendertarget texture, scaling */
2622     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2623         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2624         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2625
2626         /* We can't lock rendertarget textures, so copy to our temp surface first */
2627         if (hr == D3D_OK) {
2628             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2629             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2630         }
2631
2632         if (hr == D3D_OK) {
2633             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2634             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2635         }
2636     }
2637
2638     /* texture ==> rendertarget surface, scaling */
2639     if(surf_tex32 && surf_rt_dest64) {
2640         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2641         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2642
2643         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2644         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2645     }
2646
2647     /* texture ==> texture, scaling (should fail) */
2648     if(surf_tex32 && surf_tex_dest64) {
2649         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2650         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2651     }
2652
2653     /*****************************************************************
2654      * Tests for when the source parameter is a rendertarget texture *
2655      *****************************************************************/
2656
2657     /* Fill the surface of the rendertarget texture with white */
2658     if (surf_tex_rt64 && surf_temp64) {
2659         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2660         fill_surface(surf_temp64, 0xffffffff);
2661         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2662         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2663     }
2664
2665     /* rendertarget texture ==> offscreenplain, same size */
2666     if(surf_tex_rt64 && surf_offscreen64) {
2667         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2668         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2669     }
2670
2671     /* rendertarget texture ==> rendertarget texture, same size */
2672     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2673         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2674         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2675
2676         /* We can't lock rendertarget textures, so copy to our temp surface first */
2677         if (hr == D3D_OK) {
2678             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2679             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2680         }
2681
2682         if (hr == D3D_OK) {
2683             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2684             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2685         }
2686
2687         /* Blit without scaling */
2688         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2689         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2690
2691         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2692         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2693         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2694
2695         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2696         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2697         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2698     }
2699
2700     /* rendertarget texture ==> rendertarget surface, same size */
2701     if(surf_tex_rt64 && surf_rt_dest64) {
2702         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2703         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2704
2705         if (hr == D3D_OK) {
2706             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2707             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2708         }
2709
2710         /* Blit without scaling */
2711         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2712         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2713
2714         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2715         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2716         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2717
2718         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2719         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2720         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2721     }
2722
2723     /* rendertarget texture ==> texture, same size (should fail) */
2724     if(surf_tex_rt64 && surf_tex_dest64) {
2725         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2726         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2727     }
2728
2729     /* Fill the surface of the smaller rendertarget texture with red */
2730     if (surf_tex_rt32 && surf_temp32) {
2731         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2732         fill_surface(surf_temp32, 0xffff0000);
2733         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2734         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2735     }
2736
2737     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2738     if(surf_tex_rt32 && surf_offscreen64) {
2739         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2740         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2741     }
2742
2743     /* rendertarget texture ==> rendertarget texture, scaling */
2744     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2745         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2746         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2747
2748         /* We can't lock rendertarget textures, so copy to our temp surface first */
2749         if (hr == D3D_OK) {
2750             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2751             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2752         }
2753
2754         if (hr == D3D_OK) {
2755             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2756             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2757         }
2758     }
2759
2760     /* rendertarget texture ==> rendertarget surface, scaling */
2761     if(surf_tex_rt32 && surf_rt_dest64) {
2762         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2763         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2764
2765         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2766         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2767     }
2768
2769     /* rendertarget texture ==> texture, scaling (should fail) */
2770     if(surf_tex_rt32 && surf_tex_dest64) {
2771         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2772         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2773     }
2774
2775     /*****************************************************************
2776      * Tests for when the source parameter is a rendertarget surface *
2777      *****************************************************************/
2778
2779     /* Fill the surface of the rendertarget surface with black */
2780     if (surf_rt64)
2781         fill_surface(surf_rt64, 0xff000000);
2782
2783     /* rendertarget texture ==> offscreenplain, same size */
2784     if(surf_rt64 && surf_offscreen64) {
2785         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2786         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2787     }
2788
2789     /* rendertarget surface ==> rendertarget texture, same size */
2790     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2791         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2792         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2793
2794         /* We can't lock rendertarget textures, so copy to our temp surface first */
2795         if (hr == D3D_OK) {
2796             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2797             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2798         }
2799
2800         if (hr == D3D_OK) {
2801             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2802             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2803         }
2804
2805         /* Blit without scaling */
2806         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2807         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808
2809         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2810         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2811         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2812
2813         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2814         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2815         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2816     }
2817
2818     /* rendertarget surface ==> rendertarget surface, same size */
2819     if(surf_rt64 && surf_rt_dest64) {
2820         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2821         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2822
2823         if (hr == D3D_OK) {
2824             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2825             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2826         }
2827
2828         /* Blit without scaling */
2829         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2830         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2831
2832         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2833         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2834         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2835
2836         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2837         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2838         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2839     }
2840
2841     /* rendertarget surface ==> texture, same size (should fail) */
2842     if(surf_rt64 && surf_tex_dest64) {
2843         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2844         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2845     }
2846
2847     /* Fill the surface of the smaller rendertarget texture with red */
2848     if (surf_rt32)
2849         fill_surface(surf_rt32, 0xffff0000);
2850
2851     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2852     if(surf_rt32 && surf_offscreen64) {
2853         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2854         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2855     }
2856
2857     /* rendertarget surface ==> rendertarget texture, scaling */
2858     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2859         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2860         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861
2862         /* We can't lock rendertarget textures, so copy to our temp surface first */
2863         if (hr == D3D_OK) {
2864             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2865             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2866         }
2867
2868         if (hr == D3D_OK) {
2869             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2870             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2871         }
2872     }
2873
2874     /* rendertarget surface ==> rendertarget surface, scaling */
2875     if(surf_rt32 && surf_rt_dest64) {
2876         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2877         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2878
2879         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2880         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2881     }
2882
2883     /* rendertarget surface ==> texture, scaling (should fail) */
2884     if(surf_rt32 && surf_tex_dest64) {
2885         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2886         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2887     }
2888
2889     /* backbuffer ==> surface tests (no scaling) */
2890     if(backbuffer && surf_tex_rt_dest640_480)
2891     {
2892         RECT src_rect = {0, 0, 640, 480};
2893         RECT src_rect_flipy = {0, 480, 640, 0};
2894         RECT dst_rect = {0, 0, 640, 480};
2895         RECT dst_rect_flipy = {0, 480, 640, 0};
2896
2897         /* Blit with NULL rectangles */
2898         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2899         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2900
2901         /* Blit without scaling */
2902         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2903         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2904
2905         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2906         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2907         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2908
2909         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2910         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2911         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2912     }
2913
2914     /* TODO: Test format conversions */
2915
2916
2917 out:
2918     /* Clean up */
2919     if (backbuffer)
2920         IDirect3DSurface9_Release(backbuffer);
2921     if (surf_rt32)
2922         IDirect3DSurface9_Release(surf_rt32);
2923     if (surf_rt64)
2924         IDirect3DSurface9_Release(surf_rt64);
2925     if (surf_rt_dest64)
2926         IDirect3DSurface9_Release(surf_rt_dest64);
2927     if (surf_temp32)
2928         IDirect3DSurface9_Release(surf_temp32);
2929     if (surf_temp64)
2930         IDirect3DSurface9_Release(surf_temp64);
2931     if (surf_offscreen32)
2932         IDirect3DSurface9_Release(surf_offscreen32);
2933     if (surf_offscreen64)
2934         IDirect3DSurface9_Release(surf_offscreen64);
2935     if (surf_offscreen_dest64)
2936         IDirect3DSurface9_Release(surf_offscreen_dest64);
2937
2938     if (tex_rt32) {
2939         if (surf_tex_rt32)
2940             IDirect3DSurface9_Release(surf_tex_rt32);
2941         IDirect3DTexture9_Release(tex_rt32);
2942     }
2943     if (tex_rt64) {
2944         if (surf_tex_rt64)
2945             IDirect3DSurface9_Release(surf_tex_rt64);
2946         IDirect3DTexture9_Release(tex_rt64);
2947     }
2948     if (tex_rt_dest64) {
2949         if (surf_tex_rt_dest64)
2950             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2951         IDirect3DTexture9_Release(tex_rt_dest64);
2952     }
2953     if (tex_rt_dest640_480) {
2954         if (surf_tex_rt_dest640_480)
2955             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2956         IDirect3DTexture9_Release(tex_rt_dest640_480);
2957     }
2958     if (tex32) {
2959         if (surf_tex32)
2960             IDirect3DSurface9_Release(surf_tex32);
2961         IDirect3DTexture9_Release(tex32);
2962     }
2963     if (tex64) {
2964         if (surf_tex64)
2965             IDirect3DSurface9_Release(surf_tex64);
2966         IDirect3DTexture9_Release(tex64);
2967     }
2968     if (tex_dest64) {
2969         if (surf_tex_dest64)
2970             IDirect3DSurface9_Release(surf_tex_dest64);
2971         IDirect3DTexture9_Release(tex_dest64);
2972     }
2973
2974     if (orig_rt) {
2975         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2976         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2977         IDirect3DSurface9_Release(orig_rt);
2978     }
2979 }
2980
2981 static void maxmip_test(IDirect3DDevice9 *device)
2982 {
2983     IDirect3DTexture9 *texture = NULL;
2984     IDirect3DSurface9 *surface = NULL;
2985     HRESULT hr;
2986     DWORD color;
2987     static const struct
2988     {
2989         struct
2990         {
2991             float x, y, z;
2992             float s, t;
2993         }
2994         v[4];
2995     }
2996     quads[] =
2997     {
2998         {{
2999             {-1.0, -1.0,  0.0,  0.0,  0.0},
3000             {-1.0,  0.0,  0.0,  0.0,  1.0},
3001             { 0.0, -1.0,  0.0,  1.0,  0.0},
3002             { 0.0,  0.0,  0.0,  1.0,  1.0},
3003         }},
3004         {{
3005             { 0.0, -1.0,  0.0,  0.0,  0.0},
3006             { 0.0,  0.0,  0.0,  0.0,  1.0},
3007             { 1.0, -1.0,  0.0,  1.0,  0.0},
3008             { 1.0,  0.0,  0.0,  1.0,  1.0},
3009         }},
3010         {{
3011             { 0.0,  0.0,  0.0,  0.0,  0.0},
3012             { 0.0,  1.0,  0.0,  0.0,  1.0},
3013             { 1.0,  0.0,  0.0,  1.0,  0.0},
3014             { 1.0,  1.0,  0.0,  1.0,  1.0},
3015         }},
3016         {{
3017             {-1.0,  0.0,  0.0,  0.0,  0.0},
3018             {-1.0,  1.0,  0.0,  0.0,  1.0},
3019             { 0.0,  0.0,  0.0,  1.0,  0.0},
3020             { 0.0,  1.0,  0.0,  1.0,  1.0},
3021         }},
3022     };
3023
3024     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3025                                         &texture, NULL);
3026     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3027     if(!texture)
3028     {
3029         skip("Failed to create test texture\n");
3030         return;
3031     }
3032
3033     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3034     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3035     fill_surface(surface, 0xffff0000);
3036     IDirect3DSurface9_Release(surface);
3037     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3038     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3039     fill_surface(surface, 0xff00ff00);
3040     IDirect3DSurface9_Release(surface);
3041     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3042     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3043     fill_surface(surface, 0xff0000ff);
3044     IDirect3DSurface9_Release(surface);
3045
3046     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3048     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3049     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3050
3051     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3052     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3053
3054     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3055     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3056
3057     hr = IDirect3DDevice9_BeginScene(device);
3058     if(SUCCEEDED(hr))
3059     {
3060         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3061         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3063         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3064
3065         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3066         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3067         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3068         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3069
3070         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3071         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3072         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3073         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3074
3075         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3076         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3077         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3078         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3079         hr = IDirect3DDevice9_EndScene(device);
3080         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3081     }
3082
3083     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3084     color = getPixelColor(device, 160, 360);
3085     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3086     color = getPixelColor(device, 480, 360);
3087     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3088     color = getPixelColor(device, 480, 120);
3089     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3090     color = getPixelColor(device, 160, 120);
3091     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3092     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3093     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3094
3095     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3096     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3097
3098     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3099     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3100
3101     hr = IDirect3DDevice9_BeginScene(device);
3102     if(SUCCEEDED(hr))
3103     {
3104         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3105         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3107         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3108
3109         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3110         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3111         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3112         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3113
3114         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3115         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3116         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3117         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3118
3119         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3120         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3122         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3123         hr = IDirect3DDevice9_EndScene(device);
3124         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3125     }
3126
3127     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3128      * level 3 (> levels in texture) samples from the highest level in the
3129      * texture (level 2). */
3130     color = getPixelColor(device, 160, 360);
3131     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3132     color = getPixelColor(device, 480, 360);
3133     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3134     color = getPixelColor(device, 480, 120);
3135     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3136     color = getPixelColor(device, 160, 120);
3137     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3138     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3139     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3140
3141     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3142     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3143
3144     hr = IDirect3DDevice9_BeginScene(device);
3145     if(SUCCEEDED(hr))
3146     {
3147         DWORD ret;
3148
3149         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3150         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3151         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3152         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3153         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3154         ret = IDirect3DTexture9_SetLOD(texture, 1);
3155         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3157         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3158
3159         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3160         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3161         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3162         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3163         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3164         ret = IDirect3DTexture9_SetLOD(texture, 2);
3165         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3166         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3167         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3168
3169         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3170         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3171         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3172         ret = IDirect3DTexture9_SetLOD(texture, 1);
3173         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3174         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3175         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3176
3177         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3178         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3179         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3180         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3181         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3182         ret = IDirect3DTexture9_SetLOD(texture, 1);
3183         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3184         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3185         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3186         hr = IDirect3DDevice9_EndScene(device);
3187     }
3188
3189     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3190      * level 3 (> levels in texture) samples from the highest level in the
3191      * texture (level 2). */
3192     color = getPixelColor(device, 160, 360);
3193     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3194     color = getPixelColor(device, 480, 360);
3195     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3196     color = getPixelColor(device, 480, 120);
3197     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3198     color = getPixelColor(device, 160, 120);
3199     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3200
3201     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3202     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3203
3204     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3205     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3206     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3207     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3208     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3209     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3210     IDirect3DTexture9_Release(texture);
3211 }
3212
3213 static void release_buffer_test(IDirect3DDevice9 *device)
3214 {
3215     IDirect3DVertexBuffer9 *vb = NULL;
3216     IDirect3DIndexBuffer9 *ib = NULL;
3217     HRESULT hr;
3218     BYTE *data;
3219     LONG ref;
3220
3221     static const struct vertex quad[] = {
3222         {-1.0,      -1.0,       0.1,        0xffff0000},
3223         {-1.0,       1.0,       0.1,        0xffff0000},
3224         { 1.0,       1.0,       0.1,        0xffff0000},
3225
3226         {-1.0,      -1.0,       0.1,        0xff00ff00},
3227         {-1.0,       1.0,       0.1,        0xff00ff00},
3228         { 1.0,       1.0,       0.1,        0xff00ff00}
3229     };
3230     short indices[] = {3, 4, 5};
3231
3232     /* Index and vertex buffers should always be creatable */
3233     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3234                                               D3DPOOL_MANAGED, &vb, NULL);
3235     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3236     if(!vb) {
3237         skip("Failed to create a vertex buffer\n");
3238         return;
3239     }
3240     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3241     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3242     if(!ib) {
3243         skip("Failed to create an index buffer\n");
3244         return;
3245     }
3246
3247     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3248     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3249     memcpy(data, quad, sizeof(quad));
3250     hr = IDirect3DVertexBuffer9_Unlock(vb);
3251     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3252
3253     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3254     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3255     memcpy(data, indices, sizeof(indices));
3256     hr = IDirect3DIndexBuffer9_Unlock(ib);
3257     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3258
3259     hr = IDirect3DDevice9_SetIndices(device, ib);
3260     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3261     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3262     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3263     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3264     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3265
3266     /* Now destroy the bound index buffer and draw again */
3267     ref = IDirect3DIndexBuffer9_Release(ib);
3268     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3269
3270     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3271     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3272
3273     hr = IDirect3DDevice9_BeginScene(device);
3274     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3275     if(SUCCEEDED(hr))
3276     {
3277         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3278          * making assumptions about the indices or vertices
3279          */
3280         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3281         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3282         hr = IDirect3DDevice9_EndScene(device);
3283         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3284     }
3285
3286     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3287     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3288
3289     hr = IDirect3DDevice9_SetIndices(device, NULL);
3290     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3291     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3292     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3293
3294     /* Index buffer was already destroyed as part of the test */
3295     IDirect3DVertexBuffer9_Release(vb);
3296 }
3297
3298 static void float_texture_test(IDirect3DDevice9 *device)
3299 {
3300     IDirect3D9 *d3d = NULL;
3301     HRESULT hr;
3302     IDirect3DTexture9 *texture = NULL;
3303     D3DLOCKED_RECT lr;
3304     float *data;
3305     DWORD color;
3306     float quad[] = {
3307         -1.0,      -1.0,       0.1,     0.0,    0.0,
3308         -1.0,       1.0,       0.1,     0.0,    1.0,
3309          1.0,      -1.0,       0.1,     1.0,    0.0,
3310          1.0,       1.0,       0.1,     1.0,    1.0,
3311     };
3312
3313     memset(&lr, 0, sizeof(lr));
3314     IDirect3DDevice9_GetDirect3D(device, &d3d);
3315     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3316                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3317         skip("D3DFMT_R32F textures not supported\n");
3318         goto out;
3319     }
3320
3321     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3322                                         D3DPOOL_MANAGED, &texture, NULL);
3323     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3324     if(!texture) {
3325         skip("Failed to create R32F texture\n");
3326         goto out;
3327     }
3328
3329     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3330     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3331     data = lr.pBits;
3332     *data = 0.0;
3333     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3334     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3335
3336     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3337     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3338
3339     hr = IDirect3DDevice9_BeginScene(device);
3340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3341     if(SUCCEEDED(hr))
3342     {
3343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3345
3346         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3347         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3348
3349         hr = IDirect3DDevice9_EndScene(device);
3350         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3351     }
3352     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3353     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3354
3355     color = getPixelColor(device, 240, 320);
3356     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3357
3358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3359     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3360
3361 out:
3362     if(texture) IDirect3DTexture9_Release(texture);
3363     IDirect3D9_Release(d3d);
3364 }
3365
3366 static void g16r16_texture_test(IDirect3DDevice9 *device)
3367 {
3368     IDirect3D9 *d3d = NULL;
3369     HRESULT hr;
3370     IDirect3DTexture9 *texture = NULL;
3371     D3DLOCKED_RECT lr;
3372     DWORD *data;
3373     DWORD color;
3374     float quad[] = {
3375        -1.0,      -1.0,       0.1,     0.0,    0.0,
3376        -1.0,       1.0,       0.1,     0.0,    1.0,
3377         1.0,      -1.0,       0.1,     1.0,    0.0,
3378         1.0,       1.0,       0.1,     1.0,    1.0,
3379     };
3380
3381     memset(&lr, 0, sizeof(lr));
3382     IDirect3DDevice9_GetDirect3D(device, &d3d);
3383     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3384        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3385            skip("D3DFMT_G16R16 textures not supported\n");
3386            goto out;
3387     }
3388
3389     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3390                                         D3DPOOL_MANAGED, &texture, NULL);
3391     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3392     if(!texture) {
3393         skip("Failed to create D3DFMT_G16R16 texture\n");
3394         goto out;
3395     }
3396
3397     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3398     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3399     data = lr.pBits;
3400     *data = 0x0f00f000;
3401     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3402     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3403
3404     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3405     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3406
3407     hr = IDirect3DDevice9_BeginScene(device);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3409     if(SUCCEEDED(hr))
3410     {
3411         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3412         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3413
3414         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3415         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3416
3417         hr = IDirect3DDevice9_EndScene(device);
3418         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3419     }
3420     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3422
3423     color = getPixelColor(device, 240, 320);
3424     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3425        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3426
3427     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3428     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3429
3430 out:
3431     if(texture) IDirect3DTexture9_Release(texture);
3432     IDirect3D9_Release(d3d);
3433 }
3434
3435 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3436 {
3437     HRESULT hr;
3438     IDirect3D9 *d3d;
3439     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3440     D3DCAPS9 caps;
3441     IDirect3DTexture9 *texture = NULL;
3442     IDirect3DVolumeTexture9 *volume = NULL;
3443     unsigned int x, y, z;
3444     D3DLOCKED_RECT lr;
3445     D3DLOCKED_BOX lb;
3446     DWORD color;
3447     UINT w, h;
3448     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3449     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3450                            0.0, 1.0, 0.0, 0.0,
3451                            0.0, 0.0, 1.0, 0.0,
3452                            0.0, 0.0, 0.0, 1.0};
3453     static const D3DVERTEXELEMENT9 decl_elements[] = {
3454         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3455         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3456         D3DDECL_END()
3457     };
3458     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3459         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3460         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3461         D3DDECL_END()
3462     };
3463     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3464         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3465         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3466         D3DDECL_END()
3467     };
3468     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3469                                                  0x00, 0xff, 0x00, 0x00,
3470                                                  0x00, 0x00, 0x00, 0x00,
3471                                                  0x00, 0x00, 0x00, 0x00};
3472
3473     memset(&lr, 0, sizeof(lr));
3474     memset(&lb, 0, sizeof(lb));
3475     IDirect3DDevice9_GetDirect3D(device, &d3d);
3476     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3477                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3478         fmt = D3DFMT_A16B16G16R16;
3479     }
3480     IDirect3D9_Release(d3d);
3481
3482     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3483     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3484     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3486     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3487     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3488     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3489     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3490     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3491     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3492     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3493     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3494     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3495     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3496     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3497     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3498     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3499     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3500     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3501     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3502     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3503     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3504     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3505     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3506
3507     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3508     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3509     w = min(1024, caps.MaxTextureWidth);
3510     h = min(1024, caps.MaxTextureHeight);
3511     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3512                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3513     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3514     if(!texture) {
3515         skip("Failed to create the test texture\n");
3516         return;
3517     }
3518
3519     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3520      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3521      * 1.0 in red and green for the x and y coords
3522      */
3523     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3524     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3525     for(y = 0; y < h; y++) {
3526         for(x = 0; x < w; x++) {
3527             double r_f = (double) y / (double) h;
3528             double g_f = (double) x / (double) w;
3529             if(fmt == D3DFMT_A16B16G16R16) {
3530                 unsigned short r, g;
3531                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3532                 r = (unsigned short) (r_f * 65536.0);
3533                 g = (unsigned short) (g_f * 65536.0);
3534                 dst[0] = r;
3535                 dst[1] = g;
3536                 dst[2] = 0;
3537                 dst[3] = 65535;
3538             } else {
3539                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3540                 unsigned char r = (unsigned char) (r_f * 255.0);
3541                 unsigned char g = (unsigned char) (g_f * 255.0);
3542                 dst[0] = 0;
3543                 dst[1] = g;
3544                 dst[2] = r;
3545                 dst[3] = 255;
3546             }
3547         }
3548     }
3549     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3550     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3551     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3552     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3553
3554     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3555     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3556     hr = IDirect3DDevice9_BeginScene(device);
3557     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3558     if(SUCCEEDED(hr))
3559     {
3560         float quad1[] = {
3561             -1.0,      -1.0,       0.1,     1.0,    1.0,
3562             -1.0,       0.0,       0.1,     1.0,    1.0,
3563              0.0,      -1.0,       0.1,     1.0,    1.0,
3564              0.0,       0.0,       0.1,     1.0,    1.0,
3565         };
3566         float quad2[] = {
3567             -1.0,       0.0,       0.1,     1.0,    1.0,
3568             -1.0,       1.0,       0.1,     1.0,    1.0,
3569              0.0,       0.0,       0.1,     1.0,    1.0,
3570              0.0,       1.0,       0.1,     1.0,    1.0,
3571         };
3572         float quad3[] = {
3573              0.0,       0.0,       0.1,     0.5,    0.5,
3574              0.0,       1.0,       0.1,     0.5,    0.5,
3575              1.0,       0.0,       0.1,     0.5,    0.5,
3576              1.0,       1.0,       0.1,     0.5,    0.5,
3577         };
3578         float quad4[] = {
3579              320,       480,       0.1,     1.0,    0.0,    1.0,
3580              320,       240,       0.1,     1.0,    0.0,    1.0,
3581              640,       480,       0.1,     1.0,    0.0,    1.0,
3582              640,       240,       0.1,     1.0,    0.0,    1.0,
3583         };
3584         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3585                           0.0, 0.0, 0.0, 0.0,
3586                           0.0, 0.0, 0.0, 0.0,
3587                           0.0, 0.0, 0.0, 0.0};
3588
3589         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3590         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3591         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3592         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3593         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3594
3595         /* What happens with transforms enabled? */
3596         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3597         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3598         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3599         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3600
3601         /* What happens if 4 coords are used, but only 2 given ?*/
3602         mat[8] = 1.0;
3603         mat[13] = 1.0;
3604         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3605         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3606         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3607         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3608         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3609         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3610
3611         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3612          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3613          * due to the coords in the vertices. (turns out red, indeed)
3614          */
3615         memset(mat, 0, sizeof(mat));
3616         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3617         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3618         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3619         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3620         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3621         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3622         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3623         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3624
3625         hr = IDirect3DDevice9_EndScene(device);
3626         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3627     }
3628     color = getPixelColor(device, 160, 360);
3629     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3630     color = getPixelColor(device, 160, 120);
3631     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3632     color = getPixelColor(device, 480, 120);
3633     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3634     color = getPixelColor(device, 480, 360);
3635     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3636     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3637     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3638
3639     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3640     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3641
3642     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3644     hr = IDirect3DDevice9_BeginScene(device);
3645     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3646     if(SUCCEEDED(hr))
3647     {
3648         float quad1[] = {
3649             -1.0,      -1.0,       0.1,     0.8,    0.2,
3650             -1.0,       0.0,       0.1,     0.8,    0.2,
3651              0.0,      -1.0,       0.1,     0.8,    0.2,
3652              0.0,       0.0,       0.1,     0.8,    0.2,
3653         };
3654         float quad2[] = {
3655             -1.0,       0.0,       0.1,     0.5,    1.0,
3656             -1.0,       1.0,       0.1,     0.5,    1.0,
3657              0.0,       0.0,       0.1,     0.5,    1.0,
3658              0.0,       1.0,       0.1,     0.5,    1.0,
3659         };
3660         float quad3[] = {
3661              0.0,       0.0,       0.1,     0.5,    1.0,
3662              0.0,       1.0,       0.1,     0.5,    1.0,
3663              1.0,       0.0,       0.1,     0.5,    1.0,
3664              1.0,       1.0,       0.1,     0.5,    1.0,
3665         };
3666         float quad4[] = {
3667              0.0,      -1.0,       0.1,     0.8,    0.2,
3668              0.0,       0.0,       0.1,     0.8,    0.2,
3669              1.0,      -1.0,       0.1,     0.8,    0.2,
3670              1.0,       0.0,       0.1,     0.8,    0.2,
3671         };
3672         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3673                           0.0, 0.0, 0.0, 0.0,
3674                           0.0, 1.0, 0.0, 0.0,
3675                           0.0, 0.0, 0.0, 0.0};
3676
3677         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3678          */
3679         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3680         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3681         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3682         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3683
3684         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3685         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3686
3687         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3688          * it behaves like COUNT2 because normal textures require 2 coords
3689          */
3690         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3691         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3693         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3694
3695         /* Just to be sure, the same as quad2 above */
3696         memset(mat, 0, sizeof(mat));
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         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3702         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3703
3704         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3705          * used? And what happens to the first?
3706          */
3707         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3708         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3709         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3710         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3711
3712         hr = IDirect3DDevice9_EndScene(device);
3713         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3714     }
3715     color = getPixelColor(device, 160, 360);
3716     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3717     color = getPixelColor(device, 160, 120);
3718     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3719     color = getPixelColor(device, 480, 120);
3720     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3721        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3722     color = getPixelColor(device, 480, 360);
3723     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3724        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3725     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3726     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3727
3728     IDirect3DTexture9_Release(texture);
3729
3730     /* Test projected textures, without any fancy matrices */
3731     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3733     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3734     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3735     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3736     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3737     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3739
3740     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3741     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3742     for(x = 0; x < 4; x++) {
3743         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3744     }
3745     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3746     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3747     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3748     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3749
3750     hr = IDirect3DDevice9_BeginScene(device);
3751     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3752     if(SUCCEEDED(hr))
3753     {
3754         const float proj_quads[] = {
3755            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3756             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3757            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3758             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3759            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3760             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3761            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3762             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3763         };
3764
3765         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3766         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3768         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3769
3770         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3771         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3772         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3773         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3774
3775         hr = IDirect3DDevice9_EndScene(device);
3776         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3777     }
3778
3779     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3781     IDirect3DTexture9_Release(texture);
3782
3783     color = getPixelColor(device, 158, 118);
3784     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3785     color = getPixelColor(device, 162, 118);
3786     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3787     color = getPixelColor(device, 158, 122);
3788     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3789     color = getPixelColor(device, 162, 122);
3790     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3791
3792     color = getPixelColor(device, 158, 178);
3793     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3794     color = getPixelColor(device, 162, 178);
3795     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3796     color = getPixelColor(device, 158, 182);
3797     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3798     color = getPixelColor(device, 162, 182);
3799     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3800
3801     color = getPixelColor(device, 318, 118);
3802     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 322, 118);
3804     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 318, 122);
3806     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3807     color = getPixelColor(device, 322, 122);
3808     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3809
3810     color = getPixelColor(device, 318, 178);
3811     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812     color = getPixelColor(device, 322, 178);
3813     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3814     color = getPixelColor(device, 318, 182);
3815     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3816     color = getPixelColor(device, 322, 182);
3817     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3818
3819     color = getPixelColor(device, 238, 298);
3820     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 242, 298);
3822     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3823     color = getPixelColor(device, 238, 302);
3824     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3825     color = getPixelColor(device, 242, 302);
3826     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3827
3828     color = getPixelColor(device, 238, 388);
3829     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3830     color = getPixelColor(device, 242, 388);
3831     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3832     color = getPixelColor(device, 238, 392);
3833     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3834     color = getPixelColor(device, 242, 392);
3835     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3836
3837     color = getPixelColor(device, 478, 298);
3838     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3839     color = getPixelColor(device, 482, 298);
3840     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3841     color = getPixelColor(device, 478, 302);
3842     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3843     color = getPixelColor(device, 482, 302);
3844     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3845
3846     color = getPixelColor(device, 478, 388);
3847     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3848     color = getPixelColor(device, 482, 388);
3849     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3850     color = getPixelColor(device, 478, 392);
3851     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3852     color = getPixelColor(device, 482, 392);
3853     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3854
3855     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3856     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3857
3858     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3859     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3860     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3861      * Thus watch out if sampling from texels between 0 and 1.
3862      */
3863     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3864     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3865        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3866     if(!volume) {
3867         skip("Failed to create a volume texture\n");
3868         goto out;
3869     }
3870
3871     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3872     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3873     for(z = 0; z < 32; z++) {
3874         for(y = 0; y < 32; y++) {
3875             for(x = 0; x < 32; x++) {
3876                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3877                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3878                 float r_f = (float) x / 31.0;
3879                 float g_f = (float) y / 31.0;
3880                 float b_f = (float) z / 31.0;
3881
3882                 if(fmt == D3DFMT_A16B16G16R16) {
3883                     unsigned short *mem_s = mem;
3884                     mem_s[0]  = r_f * 65535.0;
3885                     mem_s[1]  = g_f * 65535.0;
3886                     mem_s[2]  = b_f * 65535.0;
3887                     mem_s[3]  = 65535;
3888                 } else {
3889                     unsigned char *mem_c = mem;
3890                     mem_c[0]  = b_f * 255.0;
3891                     mem_c[1]  = g_f * 255.0;
3892                     mem_c[2]  = r_f * 255.0;
3893                     mem_c[3]  = 255;
3894                 }
3895             }
3896         }
3897     }
3898     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3899     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3900
3901     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3902     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3903
3904     hr = IDirect3DDevice9_BeginScene(device);
3905     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3906     if(SUCCEEDED(hr))
3907     {
3908         float quad1[] = {
3909             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3910             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3911              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3912              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3913         };
3914         float quad2[] = {
3915             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3916             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3917              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3918              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3919         };
3920         float quad3[] = {
3921              0.0,       0.0,       0.1,     0.0,    0.0,
3922              0.0,       1.0,       0.1,     0.0,    0.0,
3923              1.0,       0.0,       0.1,     0.0,    0.0,
3924              1.0,       1.0,       0.1,     0.0,    0.0
3925         };
3926         float quad4[] = {
3927              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3928              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3929              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3930              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3931         };
3932         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3933                          0.0, 0.0, 1.0, 0.0,
3934                          0.0, 1.0, 0.0, 0.0,
3935                          0.0, 0.0, 0.0, 1.0};
3936         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3937         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3938
3939         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3940          * values
3941          */
3942         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3943         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3944         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3945         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3946         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3947         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3948
3949         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3950          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3951          * otherwise the w will be missing(blue).
3952          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3953          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3954          */
3955         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3956         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3957         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3958         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3959
3960         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3961         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3962         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3963         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3964         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3965         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3966         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3967         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3968         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3969
3970         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3971          * disable. ATI extends it up to the amount of values needed for the volume texture
3972          */
3973         memset(mat, 0, sizeof(mat));
3974         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3975         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3976         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3977         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3978         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3979         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3980         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3981         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3982
3983         hr = IDirect3DDevice9_EndScene(device);
3984         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3985     }
3986
3987     color = getPixelColor(device, 160, 360);
3988     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3989     color = getPixelColor(device, 160, 120);
3990     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3991        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3992     color = getPixelColor(device, 480, 120);
3993     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3994     color = getPixelColor(device, 480, 360);
3995     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3996
3997     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3998     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3999
4000     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4001     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4002     hr = IDirect3DDevice9_BeginScene(device);
4003     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4004     if(SUCCEEDED(hr))
4005     {
4006         float quad1[] = {
4007             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4008             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4009              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4010              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4011         };
4012         float quad2[] = {
4013             -1.0,       0.0,       0.1,
4014             -1.0,       1.0,       0.1,
4015              0.0,       0.0,       0.1,
4016              0.0,       1.0,       0.1,
4017         };
4018         float quad3[] = {
4019              0.0,       0.0,       0.1,     1.0,
4020              0.0,       1.0,       0.1,     1.0,
4021              1.0,       0.0,       0.1,     1.0,
4022              1.0,       1.0,       0.1,     1.0
4023         };
4024         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4025                            0.0, 0.0, 0.0, 0.0,
4026                            0.0, 0.0, 0.0, 0.0,
4027                            0.0, 1.0, 0.0, 0.0};
4028         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4029                            1.0, 0.0, 0.0, 0.0,
4030                            0.0, 1.0, 0.0, 0.0,
4031                            0.0, 0.0, 1.0, 0.0};
4032         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4033         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4034
4035         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4036          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4037          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4038          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4039          * 4th *input* coordinate.
4040          */
4041         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4042         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4043         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4044         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4045         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4046         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4047
4048         /* None passed */
4049         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4050         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4051         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4052         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4053         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4054         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4055
4056         /* 4 used, 1 passed */
4057         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4058         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4059         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4060         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4062         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4063
4064         hr = IDirect3DDevice9_EndScene(device);
4065         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4066     }
4067     color = getPixelColor(device, 160, 360);
4068     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4069     color = getPixelColor(device, 160, 120);
4070     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4071     color = getPixelColor(device, 480, 120);
4072     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4073     /* Quad4: unused */
4074
4075     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4076     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4077
4078     IDirect3DVolumeTexture9_Release(volume);
4079
4080     out:
4081     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4082     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4083     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4084     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4085     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4087     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4088     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4089     IDirect3DVertexDeclaration9_Release(decl);
4090     IDirect3DVertexDeclaration9_Release(decl2);
4091     IDirect3DVertexDeclaration9_Release(decl3);
4092 }
4093
4094 static void texdepth_test(IDirect3DDevice9 *device)
4095 {
4096     IDirect3DPixelShader9 *shader;
4097     HRESULT hr;
4098     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4099     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4100     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4101     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4102     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4103     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4104     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4105     DWORD shader_code[] = {
4106         0xffff0104,                                                                 /* ps_1_4               */
4107         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4108         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4109         0x0000fffd,                                                                 /* phase                */
4110         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4111         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4112         0x0000ffff                                                                  /* end                  */
4113     };
4114     DWORD color;
4115     float vertex[] = {
4116        -1.0,   -1.0,    0.0,
4117         1.0,   -1.0,    1.0,
4118        -1.0,    1.0,    0.0,
4119         1.0,    1.0,    1.0
4120     };
4121
4122     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4123     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4124
4125     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4126     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4130     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4131     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4132     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4133     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4134     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4135
4136     /* Fill the depth buffer with a gradient */
4137     hr = IDirect3DDevice9_BeginScene(device);
4138     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4139     if(SUCCEEDED(hr))
4140     {
4141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4142         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4143         hr = IDirect3DDevice9_EndScene(device);
4144         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4145     }
4146
4147     /* Now perform the actual tests. Same geometry, but with the shader */
4148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4149     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4150     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4151     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4152     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4153     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4154
4155     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4156     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4157     hr = IDirect3DDevice9_BeginScene(device);
4158     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4159     if(SUCCEEDED(hr))
4160     {
4161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4162         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4163
4164         hr = IDirect3DDevice9_EndScene(device);
4165         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4166     }
4167
4168     color = getPixelColor(device, 158, 240);
4169     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4170     color = getPixelColor(device, 162, 240);
4171     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4172
4173     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4175
4176     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4177     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4178
4179     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4180     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4181     hr = IDirect3DDevice9_BeginScene(device);
4182     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4183     if(SUCCEEDED(hr))
4184     {
4185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4186         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4187
4188         hr = IDirect3DDevice9_EndScene(device);
4189         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4190     }
4191
4192     color = getPixelColor(device, 318, 240);
4193     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4194     color = getPixelColor(device, 322, 240);
4195     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4196
4197     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4198     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4199
4200     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4201     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4202
4203     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4204     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4205     hr = IDirect3DDevice9_BeginScene(device);
4206     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4207     if(SUCCEEDED(hr))
4208     {
4209         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4210         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4211
4212         hr = IDirect3DDevice9_EndScene(device);
4213         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4214     }
4215
4216     color = getPixelColor(device, 1, 240);
4217     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4218
4219     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4220     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4221
4222     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4223     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4224
4225     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4226     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4227     hr = IDirect3DDevice9_BeginScene(device);
4228     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4229     if(SUCCEEDED(hr))
4230     {
4231         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4232         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4233
4234         hr = IDirect3DDevice9_EndScene(device);
4235         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4236     }
4237     color = getPixelColor(device, 318, 240);
4238     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4239     color = getPixelColor(device, 322, 240);
4240     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4241
4242     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4243     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4244
4245     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4246     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4247
4248     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4249     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4250     hr = IDirect3DDevice9_BeginScene(device);
4251     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4252     if(SUCCEEDED(hr))
4253     {
4254         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4255         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4256
4257         hr = IDirect3DDevice9_EndScene(device);
4258         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4259     }
4260
4261     color = getPixelColor(device, 1, 240);
4262     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4263
4264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4265     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4266
4267     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4268     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4269
4270     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4271     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4272     hr = IDirect3DDevice9_BeginScene(device);
4273     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4274     if(SUCCEEDED(hr))
4275     {
4276         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4277         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4278
4279         hr = IDirect3DDevice9_EndScene(device);
4280         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4281     }
4282
4283     color = getPixelColor(device, 638, 240);
4284     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4285
4286     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4287     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4288
4289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4290     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4291
4292     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4293     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4294     hr = IDirect3DDevice9_BeginScene(device);
4295     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4296     if(SUCCEEDED(hr))
4297     {
4298         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4299         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4300
4301         hr = IDirect3DDevice9_EndScene(device);
4302         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4303     }
4304
4305     color = getPixelColor(device, 638, 240);
4306     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4307
4308     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4309     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4310
4311     /* Cleanup */
4312     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4313     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4314     IDirect3DPixelShader9_Release(shader);
4315
4316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4317     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4319     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4320 }
4321
4322 static void texkill_test(IDirect3DDevice9 *device)
4323 {
4324     IDirect3DPixelShader9 *shader;
4325     HRESULT hr;
4326     DWORD color;
4327
4328     const float vertex[] = {
4329     /*                          bottom  top    right    left */
4330         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4331          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4332         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4333          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4334     };
4335
4336     DWORD shader_code_11[] = {
4337     0xffff0101,                                                             /* ps_1_1                     */
4338     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4339     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4340     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4341     0x0000ffff                                                              /* end                        */
4342     };
4343     DWORD shader_code_20[] = {
4344     0xffff0200,                                                             /* ps_2_0                     */
4345     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4346     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4347     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4348     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4349     0x0000ffff                                                              /* end                        */
4350     };
4351
4352     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4353     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4354     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4355     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4356
4357     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4358     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4359     hr = IDirect3DDevice9_BeginScene(device);
4360     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4361     if(SUCCEEDED(hr))
4362     {
4363         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4364         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4365         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4366         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4367         hr = IDirect3DDevice9_EndScene(device);
4368         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4369     }
4370     color = getPixelColor(device, 63, 46);
4371     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4372     color = getPixelColor(device, 66, 46);
4373     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4374     color = getPixelColor(device, 63, 49);
4375     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4376     color = getPixelColor(device, 66, 49);
4377     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4378
4379     color = getPixelColor(device, 578, 46);
4380     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4381     color = getPixelColor(device, 575, 46);
4382     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4383     color = getPixelColor(device, 578, 49);
4384     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4385     color = getPixelColor(device, 575, 49);
4386     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4387
4388     color = getPixelColor(device, 63, 430);
4389     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4390     color = getPixelColor(device, 63, 433);
4391     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4392     color = getPixelColor(device, 66, 433);
4393     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4394     color = getPixelColor(device, 66, 430);
4395     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4396
4397     color = getPixelColor(device, 578, 430);
4398     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4399     color = getPixelColor(device, 578, 433);
4400     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4401     color = getPixelColor(device, 575, 433);
4402     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4403     color = getPixelColor(device, 575, 430);
4404     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4405
4406     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4407     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4408
4409     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4410     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4411     IDirect3DPixelShader9_Release(shader);
4412
4413     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4414     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4415     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4416     if(FAILED(hr)) {
4417         skip("Failed to create 2.0 test shader, most likely not supported\n");
4418         return;
4419     }
4420
4421     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4422     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4423     hr = IDirect3DDevice9_BeginScene(device);
4424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4425     if(SUCCEEDED(hr))
4426     {
4427         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4428         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4429         hr = IDirect3DDevice9_EndScene(device);
4430         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4431     }
4432
4433     color = getPixelColor(device, 63, 46);
4434     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4435     color = getPixelColor(device, 66, 46);
4436     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4437     color = getPixelColor(device, 63, 49);
4438     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4439     color = getPixelColor(device, 66, 49);
4440     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4441
4442     color = getPixelColor(device, 578, 46);
4443     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4444     color = getPixelColor(device, 575, 46);
4445     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4446     color = getPixelColor(device, 578, 49);
4447     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4448     color = getPixelColor(device, 575, 49);
4449     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4450
4451     color = getPixelColor(device, 63, 430);
4452     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4453     color = getPixelColor(device, 63, 433);
4454     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4455     color = getPixelColor(device, 66, 433);
4456     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4457     color = getPixelColor(device, 66, 430);
4458     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4459
4460     color = getPixelColor(device, 578, 430);
4461     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4462     color = getPixelColor(device, 578, 433);
4463     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4464     color = getPixelColor(device, 575, 433);
4465     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4466     color = getPixelColor(device, 575, 430);
4467     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4468
4469     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4470     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4471
4472     /* Cleanup */
4473     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4474     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4475     IDirect3DPixelShader9_Release(shader);
4476 }
4477
4478 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4479 {
4480     IDirect3D9 *d3d9;
4481     HRESULT hr;
4482     IDirect3DTexture9 *texture;
4483     IDirect3DPixelShader9 *shader;
4484     IDirect3DPixelShader9 *shader2;
4485     D3DLOCKED_RECT lr;
4486     DWORD color;
4487     DWORD shader_code[] = {
4488         0xffff0101,                             /* ps_1_1       */
4489         0x00000042, 0xb00f0000,                 /* tex t0       */
4490         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4491         0x0000ffff                              /* end          */
4492     };
4493     DWORD shader_code2[] = {
4494         0xffff0101,                             /* ps_1_1       */
4495         0x00000042, 0xb00f0000,                 /* tex t0       */
4496         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4497         0x0000ffff                              /* end          */
4498     };
4499
4500     float quad[] = {
4501        -1.0,   -1.0,   0.1,     0.5,    0.5,
4502         1.0,   -1.0,   0.1,     0.5,    0.5,
4503        -1.0,    1.0,   0.1,     0.5,    0.5,
4504         1.0,    1.0,   0.1,     0.5,    0.5,
4505     };
4506
4507     memset(&lr, 0, sizeof(lr));
4508     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4509     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4510                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4511     IDirect3D9_Release(d3d9);
4512     if(FAILED(hr)) {
4513         skip("No D3DFMT_X8L8V8U8 support\n");
4514         return;
4515     };
4516
4517     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4518     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4519
4520     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4521     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4522     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4523     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4524     *((DWORD *) lr.pBits) = 0x11ca3141;
4525     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4526     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4527
4528     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4529     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4530     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4531     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4532
4533     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4534     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4535     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4536     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4537     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4538     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4539
4540     hr = IDirect3DDevice9_BeginScene(device);
4541     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4542     if(SUCCEEDED(hr))
4543     {
4544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4545         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4546
4547         hr = IDirect3DDevice9_EndScene(device);
4548         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4549     }
4550     color = getPixelColor(device, 578, 430);
4551     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4552        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4553     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4554     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4555
4556     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4557     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
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 == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4570     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4571     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4572
4573     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4574     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4575     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4576     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4577     IDirect3DPixelShader9_Release(shader);
4578     IDirect3DPixelShader9_Release(shader2);
4579     IDirect3DTexture9_Release(texture);
4580 }
4581
4582 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4583 {
4584     HRESULT hr;
4585     IDirect3D9 *d3d;
4586     IDirect3DTexture9 *texture = NULL;
4587     IDirect3DSurface9 *surface;
4588     DWORD color;
4589     const RECT r1 = {256, 256, 512, 512};
4590     const RECT r2 = {512, 256, 768, 512};
4591     const RECT r3 = {256, 512, 512, 768};
4592     const RECT r4 = {512, 512, 768, 768};
4593     unsigned int x, y;
4594     D3DLOCKED_RECT lr;
4595     memset(&lr, 0, sizeof(lr));
4596
4597     IDirect3DDevice9_GetDirect3D(device, &d3d);
4598     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4599        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4600         skip("No autogenmipmap support\n");
4601         IDirect3D9_Release(d3d);
4602         return;
4603     }
4604     IDirect3D9_Release(d3d);
4605
4606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4608
4609     /* Make the mipmap big, so that a smaller mipmap is used
4610      */
4611     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4612                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4613     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4614
4615     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4616     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4617     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4618     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4619     for(y = 0; y < 1024; y++) {
4620         for(x = 0; x < 1024; x++) {
4621             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4622             POINT pt;
4623
4624             pt.x = x;
4625             pt.y = y;
4626             if(PtInRect(&r1, pt)) {
4627                 *dst = 0xffff0000;
4628             } else if(PtInRect(&r2, pt)) {
4629                 *dst = 0xff00ff00;
4630             } else if(PtInRect(&r3, pt)) {
4631                 *dst = 0xff0000ff;
4632             } else if(PtInRect(&r4, pt)) {
4633                 *dst = 0xff000000;
4634             } else {
4635                 *dst = 0xffffffff;
4636             }
4637         }
4638     }
4639     hr = IDirect3DSurface9_UnlockRect(surface);
4640     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4641     IDirect3DSurface9_Release(surface);
4642
4643     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4644     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4645     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4646     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4647
4648     hr = IDirect3DDevice9_BeginScene(device);
4649     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4650     if(SUCCEEDED(hr)) {
4651         const float quad[] =  {
4652            -0.5,   -0.5,    0.1,    0.0,    0.0,
4653            -0.5,    0.5,    0.1,    0.0,    1.0,
4654             0.5,   -0.5,    0.1,    1.0,    0.0,
4655             0.5,    0.5,    0.1,    1.0,    1.0
4656         };
4657
4658         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4659         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4660         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4661         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4662         hr = IDirect3DDevice9_EndScene(device);
4663         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4664     }
4665     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4666     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4667     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4668     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4669     IDirect3DTexture9_Release(texture);
4670
4671     color = getPixelColor(device, 200, 200);
4672     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4673     color = getPixelColor(device, 280, 200);
4674     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4675     color = getPixelColor(device, 360, 200);
4676     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4677     color = getPixelColor(device, 440, 200);
4678     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4679     color = getPixelColor(device, 200, 270);
4680     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4681     color = getPixelColor(device, 280, 270);
4682     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4683     color = getPixelColor(device, 360, 270);
4684     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4685     color = getPixelColor(device, 440, 270);
4686     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4687     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4688     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4689 }
4690
4691 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4692 {
4693     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4694     IDirect3DVertexDeclaration9 *decl;
4695     HRESULT hr;
4696     DWORD color;
4697     DWORD shader_code_11[] =  {
4698         0xfffe0101,                                         /* vs_1_1           */
4699         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4700         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4701         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4702         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4703         0x0000ffff                                          /* end              */
4704     };
4705     DWORD shader_code_11_2[] =  {
4706         0xfffe0101,                                         /* vs_1_1           */
4707         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4708         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4709         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4710         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4711         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4712         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4713         0x0000ffff                                          /* end              */
4714     };
4715     DWORD shader_code_20[] =  {
4716         0xfffe0200,                                         /* vs_2_0           */
4717         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4718         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4719         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4720         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4721         0x0000ffff                                          /* end              */
4722     };
4723     DWORD shader_code_20_2[] =  {
4724         0xfffe0200,                                         /* vs_2_0           */
4725         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4726         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4727         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4728         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4729         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4730         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4731         0x0000ffff                                          /* end              */
4732     };
4733     static const D3DVERTEXELEMENT9 decl_elements[] = {
4734         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4735         D3DDECL_END()
4736     };
4737     float quad1[] = {
4738         -1.0,   -1.0,   0.1,
4739          0.0,   -1.0,   0.1,
4740         -1.0,    0.0,   0.1,
4741          0.0,    0.0,   0.1
4742     };
4743     float quad2[] = {
4744          0.0,   -1.0,   0.1,
4745          1.0,   -1.0,   0.1,
4746          0.0,    0.0,   0.1,
4747          1.0,    0.0,   0.1
4748     };
4749     float quad3[] = {
4750          0.0,    0.0,   0.1,
4751          1.0,    0.0,   0.1,
4752          0.0,    1.0,   0.1,
4753          1.0,    1.0,   0.1
4754     };
4755     float quad4[] = {
4756         -1.0,    0.0,   0.1,
4757          0.0,    0.0,   0.1,
4758         -1.0,    1.0,   0.1,
4759          0.0,    1.0,   0.1
4760     };
4761     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4762     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4763
4764     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4765     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4766
4767     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4768     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4769     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4770     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4771     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4772     if(FAILED(hr)) shader_20 = NULL;
4773     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4774     if(FAILED(hr)) shader_20_2 = NULL;
4775     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4776     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4777
4778     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4779     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4780     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4781     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4782     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4783     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4784
4785     hr = IDirect3DDevice9_BeginScene(device);
4786     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4787     if(SUCCEEDED(hr))
4788     {
4789         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4790         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4792         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4793
4794         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4795         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4797         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4798
4799         if(shader_20) {
4800             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4801             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4802             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4803             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4804         }
4805
4806         if(shader_20_2) {
4807             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4808             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4809             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4810             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4811         }
4812
4813         hr = IDirect3DDevice9_EndScene(device);
4814         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4815     }
4816
4817     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4818     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4819     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4820     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4821
4822     color = getPixelColor(device, 160, 360);
4823     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4824        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4825     color = getPixelColor(device, 480, 360);
4826     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4827        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4828     if(shader_20) {
4829         color = getPixelColor(device, 480, 120);
4830         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4831            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4832     }
4833     if(shader_20_2) {
4834         color = getPixelColor(device, 160, 120);
4835         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4836            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4837     }
4838     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4839     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4840
4841     IDirect3DVertexDeclaration9_Release(decl);
4842     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4843     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4844     IDirect3DVertexShader9_Release(shader_11_2);
4845     IDirect3DVertexShader9_Release(shader_11);
4846 }
4847
4848 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4849 {
4850     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4851     HRESULT hr;
4852     DWORD color;
4853     DWORD shader_code_11[] =  {
4854         0xffff0101,                                         /* ps_1_1           */
4855         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4856         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4857         0x0000ffff                                          /* end              */
4858     };
4859     DWORD shader_code_12[] =  {
4860         0xffff0102,                                         /* ps_1_2           */
4861         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4862         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4863         0x0000ffff                                          /* end              */
4864     };
4865     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4866      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4867      * During development of this test, 1.3 shaders were verified too
4868      */
4869     DWORD shader_code_14[] =  {
4870         0xffff0104,                                         /* ps_1_4           */
4871         /* Try to make one constant local. It gets clamped too, although the binary contains
4872          * the bigger numbers
4873          */
4874         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4875         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4876         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4877         0x0000ffff                                          /* end              */
4878     };
4879     DWORD shader_code_20[] =  {
4880         0xffff0200,                                         /* ps_2_0           */
4881         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4882         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4883         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4884         0x0000ffff                                          /* end              */
4885     };
4886     float quad1[] = {
4887         -1.0,   -1.0,   0.1,
4888          0.0,   -1.0,   0.1,
4889         -1.0,    0.0,   0.1,
4890          0.0,    0.0,   0.1
4891     };
4892     float quad2[] = {
4893          0.0,   -1.0,   0.1,
4894          1.0,   -1.0,   0.1,
4895          0.0,    0.0,   0.1,
4896          1.0,    0.0,   0.1
4897     };
4898     float quad3[] = {
4899          0.0,    0.0,   0.1,
4900          1.0,    0.0,   0.1,
4901          0.0,    1.0,   0.1,
4902          1.0,    1.0,   0.1
4903     };
4904     float quad4[] = {
4905         -1.0,    0.0,   0.1,
4906          0.0,    0.0,   0.1,
4907         -1.0,    1.0,   0.1,
4908          0.0,    1.0,   0.1
4909     };
4910     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4911     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4912
4913     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4914     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4915
4916     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4917     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4918     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4919     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4920     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4921     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4922     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4923     if(FAILED(hr)) shader_20 = NULL;
4924
4925     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4926     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4927     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4928     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4929     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4930     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4931
4932     hr = IDirect3DDevice9_BeginScene(device);
4933     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4934     if(SUCCEEDED(hr))
4935     {
4936         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4937         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4938         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4939         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4940
4941         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4942         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4943         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4944         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4945
4946         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4947         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4948         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4949         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4950
4951         if(shader_20) {
4952             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4953             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4954             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4955             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4956         }
4957
4958         hr = IDirect3DDevice9_EndScene(device);
4959         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4960     }
4961     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4962     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4963
4964     color = getPixelColor(device, 160, 360);
4965     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4966        "quad 1 has color %08x, expected 0x00808000\n", color);
4967     color = getPixelColor(device, 480, 360);
4968     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4969        "quad 2 has color %08x, expected 0x00808000\n", color);
4970     color = getPixelColor(device, 480, 120);
4971     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4972        "quad 3 has color %08x, expected 0x00808000\n", color);
4973     if(shader_20) {
4974         color = getPixelColor(device, 160, 120);
4975         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4976            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4977     }
4978     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4979     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4980
4981     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4982     IDirect3DPixelShader9_Release(shader_14);
4983     IDirect3DPixelShader9_Release(shader_12);
4984     IDirect3DPixelShader9_Release(shader_11);
4985 }
4986
4987 static void dp2add_ps_test(IDirect3DDevice9 *device)
4988 {
4989     IDirect3DPixelShader9 *shader_dp2add = NULL;
4990     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4991     HRESULT hr;
4992     DWORD color;
4993
4994     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4995      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4996      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4997      * r0 first.
4998      * The result here for the r,g,b components should be roughly 0.5:
4999      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5000     static const DWORD shader_code_dp2add[] =  {
5001         0xffff0200,                                                             /* ps_2_0                       */
5002         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5003
5004         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5005         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5006
5007         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5008         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5009         0x0000ffff                                                              /* end                          */
5010     };
5011
5012     /* Test the _sat modifier, too.  Result here should be:
5013      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5014      *      _SAT: ==> 1.0
5015      *   ADD: (1.0 + -0.5) = 0.5
5016      */
5017     static const DWORD shader_code_dp2add_sat[] =  {
5018         0xffff0200,                                                             /* ps_2_0                           */
5019         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5020
5021         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5022         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5023         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5024
5025         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5026         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5027         0x0000ffff                                                              /* end                              */
5028     };
5029
5030     const float quad[] = {
5031         -1.0,   -1.0,   0.1,
5032          1.0,   -1.0,   0.1,
5033         -1.0,    1.0,   0.1,
5034          1.0,    1.0,   0.1
5035     };
5036
5037
5038     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5039     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5040
5041     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5042     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5043
5044     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5045     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5046
5047     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5048     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5049
5050     if (shader_dp2add) {
5051
5052         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5053         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5054
5055         hr = IDirect3DDevice9_BeginScene(device);
5056         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5057         if(SUCCEEDED(hr))
5058         {
5059             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5060             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5061
5062             hr = IDirect3DDevice9_EndScene(device);
5063             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5064         }
5065
5066         color = getPixelColor(device, 360, 240);
5067         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5068                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5069
5070         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5071         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5072
5073         IDirect3DPixelShader9_Release(shader_dp2add);
5074     } else {
5075         skip("dp2add shader creation failed\n");
5076     }
5077
5078     if (shader_dp2add_sat) {
5079
5080         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5081         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5082
5083         hr = IDirect3DDevice9_BeginScene(device);
5084         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5085         if(SUCCEEDED(hr))
5086         {
5087             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5088             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5089
5090             hr = IDirect3DDevice9_EndScene(device);
5091             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5092         }
5093
5094         color = getPixelColor(device, 360, 240);
5095         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5096                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5097
5098         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5099         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5100
5101         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5102     } else {
5103         skip("dp2add shader creation failed\n");
5104     }
5105
5106     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5107     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5108 }
5109
5110 static void cnd_test(IDirect3DDevice9 *device)
5111 {
5112     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5113     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5114     HRESULT hr;
5115     DWORD color;
5116     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5117      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5118      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5119      */
5120     DWORD shader_code_11[] =  {
5121         0xffff0101,                                                                 /* ps_1_1               */
5122         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5123         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5124         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5125         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5126         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5127         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5128         0x0000ffff                                                                  /* end                  */
5129     };
5130     DWORD shader_code_12[] =  {
5131         0xffff0102,                                                                 /* ps_1_2               */
5132         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5133         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5134         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5135         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5136         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5137         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5138         0x0000ffff                                                                  /* end                  */
5139     };
5140     DWORD shader_code_13[] =  {
5141         0xffff0103,                                                                 /* ps_1_3               */
5142         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5143         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5144         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5145         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5146         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5147         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5148         0x0000ffff                                                                  /* end                  */
5149     };
5150     DWORD shader_code_14[] =  {
5151         0xffff0104,                                                                 /* ps_1_3               */
5152         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5153         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5154         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5155         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5156         0x0000ffff                                                                  /* end                  */
5157     };
5158
5159     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5160      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5161      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5162      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5163      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5164      * good enough.
5165      *
5166      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5167      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5168      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5169      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5170      */
5171     DWORD shader_code_11_coissue[] =  {
5172         0xffff0101,                                                             /* ps_1_1                   */
5173         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5174         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5175         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5176         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5177         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5178         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5179         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5180         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5181         /* 0x40000000 = D3DSI_COISSUE */
5182         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5183         0x0000ffff                                                              /* end                      */
5184     };
5185     DWORD shader_code_12_coissue[] =  {
5186         0xffff0102,                                                             /* ps_1_2                   */
5187         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5188         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5189         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5190         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5191         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5192         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5193         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5194         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5195         /* 0x40000000 = D3DSI_COISSUE */
5196         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5197         0x0000ffff                                                              /* end                      */
5198     };
5199     DWORD shader_code_13_coissue[] =  {
5200         0xffff0103,                                                             /* ps_1_3                   */
5201         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5202         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5203         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5204         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5205         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5206         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5207         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5208         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5209         /* 0x40000000 = D3DSI_COISSUE */
5210         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5211         0x0000ffff                                                              /* end                      */
5212     };
5213     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5214      * compare against 0.5
5215      */
5216     DWORD shader_code_14_coissue[] =  {
5217         0xffff0104,                                                             /* ps_1_4                   */
5218         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5219         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5220         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5221         /* 0x40000000 = D3DSI_COISSUE */
5222         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5223         0x0000ffff                                                              /* end                      */
5224     };
5225     float quad1[] = {
5226         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5227          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5228         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5229          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5230     };
5231     float quad2[] = {
5232          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5233          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5234          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5235          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5236     };
5237     float quad3[] = {
5238          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5239          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5240          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5241          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5242     };
5243     float quad4[] = {
5244         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5245          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5246         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5247          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5248     };
5249     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5250     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5251     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5252     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5253
5254     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5255     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5256
5257     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5258     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5259     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5260     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5261     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5262     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5263     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5264     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5265     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5266     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5267     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5268     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5269     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5270     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5271     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5272     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5273
5274     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5275     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5276     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5277     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5278     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5279     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5280
5281     hr = IDirect3DDevice9_BeginScene(device);
5282     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5283     if(SUCCEEDED(hr))
5284     {
5285         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5286         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5287         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5288         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5289
5290         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5291         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5292         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5293         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5294
5295         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5296         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5297         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5298         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5299
5300         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5301         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5302         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5303         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5304
5305         hr = IDirect3DDevice9_EndScene(device);
5306         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5307     }
5308
5309     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5310     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5311
5312     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5313     color = getPixelColor(device, 158, 118);
5314     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5315     color = getPixelColor(device, 162, 118);
5316     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5317     color = getPixelColor(device, 158, 122);
5318     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5319     color = getPixelColor(device, 162, 122);
5320     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5321
5322     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5323     color = getPixelColor(device, 158, 358);
5324     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5325     color = getPixelColor(device, 162, 358);
5326     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5327         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5328     color = getPixelColor(device, 158, 362);
5329     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5330     color = getPixelColor(device, 162, 362);
5331     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5332         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5333
5334     /* 1.2 shader */
5335     color = getPixelColor(device, 478, 358);
5336     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5337     color = getPixelColor(device, 482, 358);
5338     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5339         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5340     color = getPixelColor(device, 478, 362);
5341     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5342     color = getPixelColor(device, 482, 362);
5343     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5344         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5345
5346     /* 1.3 shader */
5347     color = getPixelColor(device, 478, 118);
5348     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5349     color = getPixelColor(device, 482, 118);
5350     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5351         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5352     color = getPixelColor(device, 478, 122);
5353     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5354     color = getPixelColor(device, 482, 122);
5355     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5356         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5357
5358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5359     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5360
5361     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5362     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5363     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5364     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5365     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5366     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5367
5368     hr = IDirect3DDevice9_BeginScene(device);
5369     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5370     if(SUCCEEDED(hr))
5371     {
5372         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5373         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5374         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5375         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5376
5377         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5378         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5379         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5380         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5381
5382         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5383         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5384         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5385         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5386
5387         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5388         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5389         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5390         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5391
5392         hr = IDirect3DDevice9_EndScene(device);
5393         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5394     }
5395
5396     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5397     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5398
5399     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5400      * that we swapped the values in c1 and c2 to make the other tests return some color
5401      */
5402     color = getPixelColor(device, 158, 118);
5403     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5404     color = getPixelColor(device, 162, 118);
5405     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5406     color = getPixelColor(device, 158, 122);
5407     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5408     color = getPixelColor(device, 162, 122);
5409     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5410
5411     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5412      * (The Win7 nvidia driver always selects c2)
5413      */
5414     color = getPixelColor(device, 158, 358);
5415     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5416         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5417     color = getPixelColor(device, 162, 358);
5418     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5419         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5420     color = getPixelColor(device, 158, 362);
5421     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5422         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5423     color = getPixelColor(device, 162, 362);
5424     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5425         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5426
5427     /* 1.2 shader */
5428     color = getPixelColor(device, 478, 358);
5429     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5430         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5431     color = getPixelColor(device, 482, 358);
5432     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5433         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5434     color = getPixelColor(device, 478, 362);
5435     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5436         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5437     color = getPixelColor(device, 482, 362);
5438     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5439         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5440
5441     /* 1.3 shader */
5442     color = getPixelColor(device, 478, 118);
5443     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5444         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5445     color = getPixelColor(device, 482, 118);
5446     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5447         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5448     color = getPixelColor(device, 478, 122);
5449     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5450         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5451     color = getPixelColor(device, 482, 122);
5452     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5453         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5454
5455     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5456     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5457
5458     IDirect3DPixelShader9_Release(shader_14_coissue);
5459     IDirect3DPixelShader9_Release(shader_13_coissue);
5460     IDirect3DPixelShader9_Release(shader_12_coissue);
5461     IDirect3DPixelShader9_Release(shader_11_coissue);
5462     IDirect3DPixelShader9_Release(shader_14);
5463     IDirect3DPixelShader9_Release(shader_13);
5464     IDirect3DPixelShader9_Release(shader_12);
5465     IDirect3DPixelShader9_Release(shader_11);
5466 }
5467
5468 static void nested_loop_test(IDirect3DDevice9 *device) {
5469     const DWORD shader_code[] = {
5470         0xffff0300,                                                             /* ps_3_0               */
5471         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5472         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5473         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5474         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5475         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5476         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5477         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5478         0x0000001d,                                                             /* endloop              */
5479         0x0000001d,                                                             /* endloop              */
5480         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5481         0x0000ffff                                                              /* end                  */
5482     };
5483     const DWORD vshader_code[] = {
5484         0xfffe0300,                                                             /* vs_3_0               */
5485         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5486         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5487         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5488         0x0000ffff                                                              /* end                  */
5489     };
5490     IDirect3DPixelShader9 *shader;
5491     IDirect3DVertexShader9 *vshader;
5492     HRESULT hr;
5493     DWORD color;
5494     const float quad[] = {
5495         -1.0,   -1.0,   0.1,
5496          1.0,   -1.0,   0.1,
5497         -1.0,    1.0,   0.1,
5498          1.0,    1.0,   0.1
5499     };
5500
5501     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5502     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5503     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5504     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5505     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5506     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5507     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5508     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5509     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5510     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5511     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5512     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5513
5514     hr = IDirect3DDevice9_BeginScene(device);
5515     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5516     if(SUCCEEDED(hr))
5517     {
5518         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5519         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5520         hr = IDirect3DDevice9_EndScene(device);
5521         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5522     }
5523
5524     color = getPixelColor(device, 360, 240);
5525     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5526        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5527
5528     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5529     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5530
5531     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5532     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5533     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5534     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5535     IDirect3DPixelShader9_Release(shader);
5536     IDirect3DVertexShader9_Release(vshader);
5537 }
5538
5539 struct varying_test_struct
5540 {
5541     const DWORD             *shader_code;
5542     IDirect3DPixelShader9   *shader;
5543     DWORD                   color, color_rhw;
5544     const char              *name;
5545     BOOL                    todo, todo_rhw;
5546 };
5547
5548 struct hugeVertex
5549 {
5550     float pos_x,        pos_y,      pos_z,      rhw;
5551     float weight_1,     weight_2,   weight_3,   weight_4;
5552     float index_1,      index_2,    index_3,    index_4;
5553     float normal_1,     normal_2,   normal_3,   normal_4;
5554     float fog_1,        fog_2,      fog_3,      fog_4;
5555     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5556     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5557     float binormal_1,   binormal_2, binormal_3, binormal_4;
5558     float depth_1,      depth_2,    depth_3,    depth_4;
5559     DWORD diffuse, specular;
5560 };
5561
5562 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5563     /* dcl_position: fails to compile */
5564     const DWORD blendweight_code[] = {
5565         0xffff0300,                             /* ps_3_0                   */
5566         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5567         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5568         0x0000ffff                              /* end                      */
5569     };
5570     const DWORD blendindices_code[] = {
5571         0xffff0300,                             /* ps_3_0                   */
5572         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5573         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5574         0x0000ffff                              /* end                      */
5575     };
5576     const DWORD normal_code[] = {
5577         0xffff0300,                             /* ps_3_0                   */
5578         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5579         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5580         0x0000ffff                              /* end                      */
5581     };
5582     /* psize: fails? */
5583     const DWORD texcoord0_code[] = {
5584         0xffff0300,                             /* ps_3_0                   */
5585         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5586         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5587         0x0000ffff                              /* end                      */
5588     };
5589     const DWORD tangent_code[] = {
5590         0xffff0300,                             /* ps_3_0                   */
5591         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5592         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5593         0x0000ffff                              /* end                      */
5594     };
5595     const DWORD binormal_code[] = {
5596         0xffff0300,                             /* ps_3_0                   */
5597         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5598         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5599         0x0000ffff                              /* end                      */
5600     };
5601     /* tessfactor: fails */
5602     /* positiont: fails */
5603     const DWORD color_code[] = {
5604         0xffff0300,                             /* ps_3_0                   */
5605         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5606         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5607         0x0000ffff                              /* end                      */
5608     };
5609     const DWORD fog_code[] = {
5610         0xffff0300,                             /* ps_3_0                   */
5611         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5612         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5613         0x0000ffff                              /* end                      */
5614     };
5615     const DWORD depth_code[] = {
5616         0xffff0300,                             /* ps_3_0                   */
5617         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5618         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5619         0x0000ffff                              /* end                      */
5620     };
5621     const DWORD specular_code[] = {
5622         0xffff0300,                             /* ps_3_0                   */
5623         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5624         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5625         0x0000ffff                              /* end                      */
5626     };
5627     /* sample: fails */
5628
5629     struct varying_test_struct tests[] = {
5630        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5631        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5632        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5633        /* Why does dx not forward the texcoord? */
5634        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5635        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5636        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5637        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5638        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5639        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5640        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5641     };
5642     /* Declare a monster vertex type :-) */
5643     static const D3DVERTEXELEMENT9 decl_elements[] = {
5644         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5645         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5646         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5647         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5648         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5649         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5650         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5651         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5652         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5653         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5654         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5655         D3DDECL_END()
5656     };
5657     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5658         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5659         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5660         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5661         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5662         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5663         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5664         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5665         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5666         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5667         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5668         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5669         D3DDECL_END()
5670     };
5671     struct hugeVertex data[4] = {
5672         {
5673             -1.0,   -1.0,   0.1,    1.0,
5674              0.1,    0.1,   0.1,    0.1,
5675              0.2,    0.2,   0.2,    0.2,
5676              0.3,    0.3,   0.3,    0.3,
5677              0.4,    0.4,   0.4,    0.4,
5678              0.50,   0.55,  0.55,   0.55,
5679              0.6,    0.6,   0.6,    0.7,
5680              0.7,    0.7,   0.7,    0.6,
5681              0.8,    0.8,   0.8,    0.8,
5682              0xe6e6e6e6, /* 0.9 * 256 */
5683              0x224488ff  /* Nothing special */
5684         },
5685         {
5686              1.0,   -1.0,   0.1,    1.0,
5687              0.1,    0.1,   0.1,    0.1,
5688              0.2,    0.2,   0.2,    0.2,
5689              0.3,    0.3,   0.3,    0.3,
5690              0.4,    0.4,   0.4,    0.4,
5691              0.50,   0.55,  0.55,   0.55,
5692              0.6,    0.6,   0.6,    0.7,
5693              0.7,    0.7,   0.7,    0.6,
5694              0.8,    0.8,   0.8,    0.8,
5695              0xe6e6e6e6, /* 0.9 * 256 */
5696              0x224488ff /* Nothing special */
5697         },
5698         {
5699             -1.0,    1.0,   0.1,    1.0,
5700              0.1,    0.1,   0.1,    0.1,
5701              0.2,    0.2,   0.2,    0.2,
5702              0.3,    0.3,   0.3,    0.3,
5703              0.4,    0.4,   0.4,    0.4,
5704              0.50,   0.55,  0.55,   0.55,
5705              0.6,    0.6,   0.6,    0.7,
5706              0.7,    0.7,   0.7,    0.6,
5707              0.8,    0.8,   0.8,    0.8,
5708              0xe6e6e6e6, /* 0.9 * 256 */
5709              0x224488ff /* Nothing special */
5710         },
5711         {
5712              1.0,    1.0,   0.1,    1.0,
5713              0.1,    0.1,   0.1,    0.1,
5714              0.2,    0.2,   0.2,    0.2,
5715              0.3,    0.3,   0.3,    0.3,
5716              0.4,    0.4,   0.4,    0.4,
5717              0.50,   0.55,  0.55,   0.55,
5718              0.6,    0.6,   0.6,    0.7,
5719              0.7,    0.7,   0.7,    0.6,
5720              0.8,    0.8,   0.8,    0.8,
5721              0xe6e6e6e6, /* 0.9 * 256 */
5722              0x224488ff /* Nothing special */
5723         },
5724     };
5725     struct hugeVertex data2[4];
5726     IDirect3DVertexDeclaration9 *decl;
5727     IDirect3DVertexDeclaration9 *decl2;
5728     HRESULT hr;
5729     unsigned int i;
5730     DWORD color, r, g, b, r_e, g_e, b_e;
5731     BOOL drawok;
5732
5733     memcpy(data2, data, sizeof(data2));
5734     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5735     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5736     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5737     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5738
5739     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5740     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5741     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5742     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5743     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5744     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5745
5746     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5747     {
5748         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5749         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5750            tests[i].name, hr);
5751     }
5752
5753     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5754     {
5755         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5756         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5757
5758         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5759         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5760
5761         hr = IDirect3DDevice9_BeginScene(device);
5762         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5763         drawok = FALSE;
5764         if(SUCCEEDED(hr))
5765         {
5766             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5767             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5768             drawok = SUCCEEDED(hr);
5769             hr = IDirect3DDevice9_EndScene(device);
5770             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5771         }
5772
5773         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5774          * the failure and do not check the color if it failed
5775          */
5776         if(!drawok) {
5777             continue;
5778         }
5779
5780         color = getPixelColor(device, 360, 240);
5781         r = color & 0x00ff0000 >> 16;
5782         g = color & 0x0000ff00 >>  8;
5783         b = color & 0x000000ff;
5784         r_e = tests[i].color & 0x00ff0000 >> 16;
5785         g_e = tests[i].color & 0x0000ff00 >>  8;
5786         b_e = tests[i].color & 0x000000ff;
5787
5788         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5789         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5790
5791         if(tests[i].todo) {
5792             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5793                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5794                          tests[i].name, color, tests[i].color);
5795         } else {
5796             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5797                "Test %s returned color 0x%08x, expected 0x%08x\n",
5798                tests[i].name, color, tests[i].color);
5799         }
5800     }
5801
5802     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5803     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5804     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5805     {
5806         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5807         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5808
5809         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5810         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5811
5812         hr = IDirect3DDevice9_BeginScene(device);
5813         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5814         if(SUCCEEDED(hr))
5815         {
5816             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5817             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5818             hr = IDirect3DDevice9_EndScene(device);
5819             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5820         }
5821
5822         color = getPixelColor(device, 360, 240);
5823         r = color & 0x00ff0000 >> 16;
5824         g = color & 0x0000ff00 >>  8;
5825         b = color & 0x000000ff;
5826         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5827         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5828         b_e = tests[i].color_rhw & 0x000000ff;
5829
5830         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5831         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5832
5833         if(tests[i].todo_rhw) {
5834             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5835              * pipeline
5836              */
5837             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5838                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5839                          tests[i].name, color, tests[i].color_rhw);
5840         } else {
5841             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5842                "Test %s returned color 0x%08x, expected 0x%08x\n",
5843                tests[i].name, color, tests[i].color_rhw);
5844         }
5845     }
5846
5847     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5848     {
5849         IDirect3DPixelShader9_Release(tests[i].shader);
5850     }
5851
5852     IDirect3DVertexDeclaration9_Release(decl2);
5853     IDirect3DVertexDeclaration9_Release(decl);
5854 }
5855
5856 static void test_compare_instructions(IDirect3DDevice9 *device)
5857 {
5858     DWORD shader_sge_vec_code[] = {
5859         0xfffe0101,                                         /* vs_1_1                   */
5860         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5861         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5862         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5863         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5864         0x0000ffff                                          /* end                      */
5865     };
5866     DWORD shader_slt_vec_code[] = {
5867         0xfffe0101,                                         /* vs_1_1                   */
5868         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5869         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5870         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5871         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5872         0x0000ffff                                          /* end                      */
5873     };
5874     DWORD shader_sge_scalar_code[] = {
5875         0xfffe0101,                                         /* vs_1_1                   */
5876         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5877         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5878         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5879         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5880         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5881         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5882         0x0000ffff                                          /* end                      */
5883     };
5884     DWORD shader_slt_scalar_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, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5890         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5891         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5892         0x0000ffff                                          /* end                      */
5893     };
5894     IDirect3DVertexShader9 *shader_sge_vec;
5895     IDirect3DVertexShader9 *shader_slt_vec;
5896     IDirect3DVertexShader9 *shader_sge_scalar;
5897     IDirect3DVertexShader9 *shader_slt_scalar;
5898     HRESULT hr, color;
5899     float quad1[] =  {
5900         -1.0,   -1.0,   0.1,
5901          0.0,   -1.0,   0.1,
5902         -1.0,    0.0,   0.1,
5903          0.0,    0.0,   0.1
5904     };
5905     float quad2[] =  {
5906          0.0,   -1.0,   0.1,
5907          1.0,   -1.0,   0.1,
5908          0.0,    0.0,   0.1,
5909          1.0,    0.0,   0.1
5910     };
5911     float quad3[] =  {
5912         -1.0,    0.0,   0.1,
5913          0.0,    0.0,   0.1,
5914         -1.0,    1.0,   0.1,
5915          0.0,    1.0,   0.1
5916     };
5917     float quad4[] =  {
5918          0.0,    0.0,   0.1,
5919          1.0,    0.0,   0.1,
5920          0.0,    1.0,   0.1,
5921          1.0,    1.0,   0.1
5922     };
5923     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5924     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5925
5926     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5927     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5928
5929     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5930     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5931     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5932     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5933     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5934     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5935     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5936     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5937     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5938     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5939     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5940     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5941     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5942     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5943
5944     hr = IDirect3DDevice9_BeginScene(device);
5945     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5946     if(SUCCEEDED(hr))
5947     {
5948         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5949         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5951         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5952
5953         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5954         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5956         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5957
5958         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5959         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5962
5963         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5964         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5965
5966         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5967         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5969         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5970
5971         hr = IDirect3DDevice9_EndScene(device);
5972         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5973     }
5974
5975     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5976     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5977
5978     color = getPixelColor(device, 160, 360);
5979     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5980     color = getPixelColor(device, 480, 360);
5981     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5982     color = getPixelColor(device, 160, 120);
5983     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5984     color = getPixelColor(device, 480, 160);
5985     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5986
5987     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5988     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5989
5990     IDirect3DVertexShader9_Release(shader_sge_vec);
5991     IDirect3DVertexShader9_Release(shader_slt_vec);
5992     IDirect3DVertexShader9_Release(shader_sge_scalar);
5993     IDirect3DVertexShader9_Release(shader_slt_scalar);
5994 }
5995
5996 static void test_vshader_input(IDirect3DDevice9 *device)
5997 {
5998     DWORD swapped_shader_code_3[] = {
5999         0xfffe0300,                                         /* vs_3_0               */
6000         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6001         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6002         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6003         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6004         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6005         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6006         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6007         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6008         0x0000ffff                                          /* end                  */
6009     };
6010     DWORD swapped_shader_code_1[] = {
6011         0xfffe0101,                                         /* vs_1_1               */
6012         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6013         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6014         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6015         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6016         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6017         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6018         0x0000ffff                                          /* end                  */
6019     };
6020     DWORD swapped_shader_code_2[] = {
6021         0xfffe0200,                                         /* vs_2_0               */
6022         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6023         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6024         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6025         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6026         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6027         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6028         0x0000ffff                                          /* end                  */
6029     };
6030     DWORD texcoord_color_shader_code_3[] = {
6031         0xfffe0300,                                         /* vs_3_0               */
6032         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6033         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6034         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6035         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6036         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6037         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6038         0x0000ffff                                          /* end                  */
6039     };
6040     DWORD texcoord_color_shader_code_2[] = {
6041         0xfffe0200,                                         /* vs_2_0               */
6042         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6043         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6044         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6045         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6046         0x0000ffff                                          /* end                  */
6047     };
6048     DWORD texcoord_color_shader_code_1[] = {
6049         0xfffe0101,                                         /* vs_1_1               */
6050         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6051         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6052         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6053         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6054         0x0000ffff                                          /* end                  */
6055     };
6056     DWORD color_color_shader_code_3[] = {
6057         0xfffe0300,                                         /* vs_3_0               */
6058         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6059         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6060         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6061         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6062         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6063         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6064         0x0000ffff                                          /* end                  */
6065     };
6066     DWORD color_color_shader_code_2[] = {
6067         0xfffe0200,                                         /* vs_2_0               */
6068         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6069         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6070         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6071         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6072         0x0000ffff                                          /* end                  */
6073     };
6074     DWORD color_color_shader_code_1[] = {
6075         0xfffe0101,                                         /* vs_1_1               */
6076         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6077         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6078         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6079         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6080         0x0000ffff                                          /* end                  */
6081     };
6082     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6083     HRESULT hr;
6084     DWORD color;
6085     float quad1[] =  {
6086         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6087          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6088         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6089          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6090     };
6091     float quad2[] =  {
6092          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6093          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6094          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6095          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6096     };
6097     float quad3[] =  {
6098         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6099          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6100         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6101          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6102     };
6103     float quad4[] =  {
6104          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6105          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6106          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6107          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6108     };
6109     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6110         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6111         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6112         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6113         D3DDECL_END()
6114     };
6115     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6116         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6117         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6118         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6119         D3DDECL_END()
6120     };
6121     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6122         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6123         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6124         D3DDECL_END()
6125     };
6126     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6127         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6128         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6129         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6130         D3DDECL_END()
6131     };
6132     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6133         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6134         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6135         D3DDECL_END()
6136     };
6137     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6138         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6139         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6140         D3DDECL_END()
6141     };
6142     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6143         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6144         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6145         D3DDECL_END()
6146     };
6147     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6148         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6149         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6150         D3DDECL_END()
6151     };
6152     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6153     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6154     unsigned int i;
6155     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6156     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6157
6158     struct vertex quad1_color[] =  {
6159        {-1.0,   -1.0,   0.1,    0x00ff8040},
6160        { 0.0,   -1.0,   0.1,    0x00ff8040},
6161        {-1.0,    0.0,   0.1,    0x00ff8040},
6162        { 0.0,    0.0,   0.1,    0x00ff8040}
6163     };
6164     struct vertex quad2_color[] =  {
6165        { 0.0,   -1.0,   0.1,    0x00ff8040},
6166        { 1.0,   -1.0,   0.1,    0x00ff8040},
6167        { 0.0,    0.0,   0.1,    0x00ff8040},
6168        { 1.0,    0.0,   0.1,    0x00ff8040}
6169     };
6170     struct vertex quad3_color[] =  {
6171        {-1.0,    0.0,   0.1,    0x00ff8040},
6172        { 0.0,    0.0,   0.1,    0x00ff8040},
6173        {-1.0,    1.0,   0.1,    0x00ff8040},
6174        { 0.0,    1.0,   0.1,    0x00ff8040}
6175     };
6176     float quad4_color[] =  {
6177          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6178          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6179          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6180          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6181     };
6182
6183     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6184     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6185     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6186     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6187     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6188     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6189     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6190     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6191
6192     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6193     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6194     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6195     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6196     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6197     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6198     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6199     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6200
6201     for(i = 1; i <= 3; i++) {
6202         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6203         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6204         if(i == 3) {
6205             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6206             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6207         } else if(i == 2){
6208             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6209             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6210         } else if(i == 1) {
6211             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6212             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6213         }
6214
6215         hr = IDirect3DDevice9_BeginScene(device);
6216         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6217         if(SUCCEEDED(hr))
6218         {
6219             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6220             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6221
6222             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6223             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6224             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6225             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6226
6227             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6228             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6229             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6230             if(i == 3 || i == 2) {
6231                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6232             } else if(i == 1) {
6233                 /* Succeeds or fails, depending on SW or HW vertex processing */
6234                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6235             }
6236
6237             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6238             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6239             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6240             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6241
6242             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6243             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6244             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6245             if(i == 3 || i == 2) {
6246                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6247             } else if(i == 1) {
6248                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6249             }
6250
6251             hr = IDirect3DDevice9_EndScene(device);
6252             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6253         }
6254
6255         if(i == 3 || i == 2) {
6256             color = getPixelColor(device, 160, 360);
6257             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6258                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6259
6260             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6261             color = getPixelColor(device, 480, 360);
6262             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6263                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6264             color = getPixelColor(device, 160, 120);
6265             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6266             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6267                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6268
6269             color = getPixelColor(device, 480, 160);
6270             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6271         } else if(i == 1) {
6272             color = getPixelColor(device, 160, 360);
6273             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6274                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6275             color = getPixelColor(device, 480, 360);
6276             /* Accept the clear color as well in this case, since SW VP returns an error */
6277             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6278             color = getPixelColor(device, 160, 120);
6279             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6280                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6281             color = getPixelColor(device, 480, 160);
6282             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6283         }
6284
6285         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6286         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6287
6288         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6289         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6290
6291         /* Now find out if the whole streams are re-read, or just the last active value for the
6292          * vertices is used.
6293          */
6294         hr = IDirect3DDevice9_BeginScene(device);
6295         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6296         if(SUCCEEDED(hr))
6297         {
6298             float quad1_modified[] =  {
6299                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6300                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6301                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6302                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6303             };
6304             float quad2_modified[] =  {
6305                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6306                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6307                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6308                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6309             };
6310
6311             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6312             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6313
6314             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6315             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6316             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6317             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6318
6319             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6320             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6321             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6322             if(i == 3 || i == 2) {
6323                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6324             } else if(i == 1) {
6325                 /* Succeeds or fails, depending on SW or HW vertex processing */
6326                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6327             }
6328
6329             hr = IDirect3DDevice9_EndScene(device);
6330             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6331         }
6332
6333         color = getPixelColor(device, 480, 350);
6334         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6335          * as well.
6336          *
6337          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6338          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6339          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6340          * refrast's result.
6341          *
6342          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6343          */
6344         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6345            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6346
6347         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6348         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6349
6350         IDirect3DDevice9_SetVertexShader(device, NULL);
6351         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6352
6353         IDirect3DVertexShader9_Release(swapped_shader);
6354     }
6355
6356     for(i = 1; i <= 3; i++) {
6357         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6358         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6359         if(i == 3) {
6360             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6361             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6362             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6363             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6364         } else if(i == 2){
6365             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6366             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6367             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6368             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6369         } else if(i == 1) {
6370             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6371             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6372             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6373             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6374         }
6375
6376         hr = IDirect3DDevice9_BeginScene(device);
6377         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6378         if(SUCCEEDED(hr))
6379         {
6380             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6381             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6382             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6383             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6384             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6385             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6386
6387             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6388             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6389
6390             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6391             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6392             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6393             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6394             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6395             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6396
6397             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6398             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6399             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6400             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6401             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6402             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6403
6404             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6405             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6406             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6407             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6408
6409             hr = IDirect3DDevice9_EndScene(device);
6410             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6411         }
6412         IDirect3DDevice9_SetVertexShader(device, NULL);
6413         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6414
6415         color = getPixelColor(device, 160, 360);
6416         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6417            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6418         color = getPixelColor(device, 480, 360);
6419         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6420            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6421         color = getPixelColor(device, 160, 120);
6422         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6423            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6424         color = getPixelColor(device, 480, 160);
6425         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6426            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6427
6428         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6429         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6430
6431         IDirect3DVertexShader9_Release(texcoord_color_shader);
6432         IDirect3DVertexShader9_Release(color_color_shader);
6433     }
6434
6435     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6436     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6437     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6438     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6439
6440     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6441     IDirect3DVertexDeclaration9_Release(decl_color_color);
6442     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6443     IDirect3DVertexDeclaration9_Release(decl_color_float);
6444 }
6445
6446 static void srgbtexture_test(IDirect3DDevice9 *device)
6447 {
6448     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6449      * texture stage state to render a quad using that texture.  The resulting
6450      * color components should be 0x36 (~ 0.21), per this formula:
6451      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6452      * This is true where srgb_color > 0.04045.
6453      */
6454     IDirect3D9 *d3d = NULL;
6455     HRESULT hr;
6456     LPDIRECT3DTEXTURE9 texture = NULL;
6457     LPDIRECT3DSURFACE9 surface = NULL;
6458     D3DLOCKED_RECT lr;
6459     DWORD color;
6460     float quad[] = {
6461         -1.0,       1.0,       0.0,     0.0,    0.0,
6462          1.0,       1.0,       0.0,     1.0,    0.0,
6463         -1.0,      -1.0,       0.0,     0.0,    1.0,
6464          1.0,      -1.0,       0.0,     1.0,    1.0,
6465     };
6466
6467
6468     memset(&lr, 0, sizeof(lr));
6469     IDirect3DDevice9_GetDirect3D(device, &d3d);
6470     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6471                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6472                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6473         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6474         goto out;
6475     }
6476
6477     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6478                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6479                                         &texture, NULL);
6480     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6481     if(!texture) {
6482         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6483         goto out;
6484     }
6485     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6486     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6487
6488     fill_surface(surface, 0xff7f7f7f);
6489     IDirect3DSurface9_Release(surface);
6490
6491     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6492     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6493     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6494     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6495
6496     hr = IDirect3DDevice9_BeginScene(device);
6497     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6498     if(SUCCEEDED(hr))
6499     {
6500         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6501         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6502
6503         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6504         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6505
6506
6507         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6508         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6509
6510         hr = IDirect3DDevice9_EndScene(device);
6511         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6512     }
6513
6514     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6515     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6516     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6517     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6518
6519     color = getPixelColor(device, 320, 240);
6520     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6521
6522     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6523     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6524
6525 out:
6526     if(texture) IDirect3DTexture9_Release(texture);
6527     IDirect3D9_Release(d3d);
6528 }
6529
6530 static void shademode_test(IDirect3DDevice9 *device)
6531 {
6532     /* Render a quad and try all of the different fixed function shading models. */
6533     HRESULT hr;
6534     DWORD color0, color1;
6535     DWORD color0_gouraud = 0, color1_gouraud = 0;
6536     DWORD shademode = D3DSHADE_FLAT;
6537     DWORD primtype = D3DPT_TRIANGLESTRIP;
6538     LPVOID data = NULL;
6539     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6540     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6541     UINT i, j;
6542     struct vertex quad_strip[] =
6543     {
6544         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6545         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6546         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6547         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6548     };
6549     struct vertex quad_list[] =
6550     {
6551         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6552         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6553         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6554
6555         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6556         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6557         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6558     };
6559
6560     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6561                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6562     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6563     if (FAILED(hr)) goto bail;
6564
6565     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6566                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6567     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6568     if (FAILED(hr)) goto bail;
6569
6570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6571     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6572
6573     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6574     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6575
6576     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6577     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6578     memcpy(data, quad_strip, sizeof(quad_strip));
6579     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6580     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6581
6582     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6583     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6584     memcpy(data, quad_list, sizeof(quad_list));
6585     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6586     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6587
6588     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6589      * the color fixups we have to do for FLAT shading will be dependent on that. */
6590     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6591     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6592
6593     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6594     for (j=0; j<2; j++) {
6595
6596         /* Inner loop just changes the D3DRS_SHADEMODE */
6597         for (i=0; i<3; i++) {
6598             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6599             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6600
6601             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6602             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6603
6604             hr = IDirect3DDevice9_BeginScene(device);
6605             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6606             if(SUCCEEDED(hr))
6607             {
6608                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6609                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6610
6611                 hr = IDirect3DDevice9_EndScene(device);
6612                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6613             }
6614
6615             /* Sample two spots from the output */
6616             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6617             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6618             switch(shademode) {
6619                 case D3DSHADE_FLAT:
6620                     /* Should take the color of the first vertex of each triangle */
6621                     if (0)
6622                     {
6623                         /* This test depends on EXT_provoking_vertex being
6624                          * available. This extension is currently (20090810)
6625                          * not common enough to let the test fail if it isn't
6626                          * present. */
6627                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6628                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6629                     }
6630                     shademode = D3DSHADE_GOURAUD;
6631                     break;
6632                 case D3DSHADE_GOURAUD:
6633                     /* Should be an interpolated blend */
6634
6635                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6636                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6637                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6638                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6639
6640                     color0_gouraud = color0;
6641                     color1_gouraud = color1;
6642
6643                     shademode = D3DSHADE_PHONG;
6644                     break;
6645                 case D3DSHADE_PHONG:
6646                     /* Should be the same as GOURAUD, since no hardware implements this */
6647                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6648                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6649                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6650                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6651
6652                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6653                             color0_gouraud, color0);
6654                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6655                             color1_gouraud, color1);
6656                     break;
6657             }
6658         }
6659
6660         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6661         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6662
6663         /* Now, do it all over again with a TRIANGLELIST */
6664         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6665         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6666         primtype = D3DPT_TRIANGLELIST;
6667         shademode = D3DSHADE_FLAT;
6668     }
6669
6670 bail:
6671     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6672     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6675
6676     if (vb_strip)
6677         IDirect3DVertexBuffer9_Release(vb_strip);
6678     if (vb_list)
6679         IDirect3DVertexBuffer9_Release(vb_list);
6680 }
6681
6682 static void alpha_test(IDirect3DDevice9 *device)
6683 {
6684     HRESULT hr;
6685     IDirect3DTexture9 *offscreenTexture;
6686     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6687     DWORD color;
6688
6689     struct vertex quad1[] =
6690     {
6691         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6692         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6693         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6694         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6695     };
6696     struct vertex quad2[] =
6697     {
6698         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6699         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6700         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6701         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6702     };
6703     static const float composite_quad[][5] = {
6704         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6705         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6706         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6707         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6708     };
6709
6710     /* Clear the render target with alpha = 0.5 */
6711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6712     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6713
6714     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6715     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6716
6717     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6718     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6719     if(!backbuffer) {
6720         goto out;
6721     }
6722
6723     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6724     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6725     if(!offscreen) {
6726         goto out;
6727     }
6728
6729     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6730     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6731
6732     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6733     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6734     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6735     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6736     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6737     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6738     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6739     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6740     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6741     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6742
6743     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6744     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6745     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6746
6747         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6748         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6749         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6750         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6751         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6753         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6754
6755         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6756         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6757         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6758         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6759         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6760         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6761
6762         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6763          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6764          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6765         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6766         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6767         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6768         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6769
6770         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6771         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6772         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6773         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6774         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6775         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6776
6777         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6778         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6779         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6780         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6781         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6782         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6783
6784         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6785         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6786
6787         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6788          * Disable alpha blending for the final composition
6789          */
6790         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6791         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6792         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6793         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6794
6795         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6796         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6797         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6798         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6799         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6800         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6801
6802         hr = IDirect3DDevice9_EndScene(device);
6803         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6804     }
6805
6806     color = getPixelColor(device, 160, 360);
6807     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6808        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6809
6810     color = getPixelColor(device, 160, 120);
6811     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6812        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6813
6814     color = getPixelColor(device, 480, 360);
6815     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6816        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6817
6818     color = getPixelColor(device, 480, 120);
6819     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6820        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6821
6822     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6823
6824     out:
6825     /* restore things */
6826     if(backbuffer) {
6827         IDirect3DSurface9_Release(backbuffer);
6828     }
6829     if(offscreenTexture) {
6830         IDirect3DTexture9_Release(offscreenTexture);
6831     }
6832     if(offscreen) {
6833         IDirect3DSurface9_Release(offscreen);
6834     }
6835 }
6836
6837 struct vertex_shortcolor {
6838     float x, y, z;
6839     unsigned short r, g, b, a;
6840 };
6841 struct vertex_floatcolor {
6842     float x, y, z;
6843     float r, g, b, a;
6844 };
6845
6846 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6847 {
6848     HRESULT hr;
6849     BOOL s_ok, ub_ok, f_ok;
6850     DWORD color, size, i;
6851     void *data;
6852     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6853         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6854         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6855         D3DDECL_END()
6856     };
6857     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6858         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6859         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6860         D3DDECL_END()
6861     };
6862     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6863         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6864         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6865         D3DDECL_END()
6866     };
6867     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6868         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6869         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6870         D3DDECL_END()
6871     };
6872     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6873         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6874         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6875         D3DDECL_END()
6876     };
6877     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6878         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6879         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6880         D3DDECL_END()
6881     };
6882     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6883         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6884         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6885         D3DDECL_END()
6886     };
6887     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6888     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6889     IDirect3DVertexBuffer9 *vb, *vb2;
6890     struct vertex quad1[] =                             /* D3DCOLOR */
6891     {
6892         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6893         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6894         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6895         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6896     };
6897     struct vertex quad2[] =                             /* UBYTE4N */
6898     {
6899         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6900         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6901         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6902         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6903     };
6904     struct vertex_shortcolor quad3[] =                  /* short */
6905     {
6906         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6907         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6908         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6909         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6910     };
6911     struct vertex_floatcolor quad4[] =
6912     {
6913         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6914         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6915         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6916         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6917     };
6918     DWORD colors[] = {
6919         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6920         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6921         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6922         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6923         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6924         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6925         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6926         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6927         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6928         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6929         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6930         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6931         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6932         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6933         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6934         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6935     };
6936     float quads[] = {
6937         -1.0,   -1.0,     0.1,
6938         -1.0,    0.0,     0.1,
6939          0.0,   -1.0,     0.1,
6940          0.0,    0.0,     0.1,
6941
6942          0.0,   -1.0,     0.1,
6943          0.0,    0.0,     0.1,
6944          1.0,   -1.0,     0.1,
6945          1.0,    0.0,     0.1,
6946
6947          0.0,    0.0,     0.1,
6948          0.0,    1.0,     0.1,
6949          1.0,    0.0,     0.1,
6950          1.0,    1.0,     0.1,
6951
6952         -1.0,    0.0,     0.1,
6953         -1.0,    1.0,     0.1,
6954          0.0,    0.0,     0.1,
6955          0.0,    1.0,     0.1
6956     };
6957     struct tvertex quad_transformed[] = {
6958        {  90,    110,     0.1,      2.0,        0x00ffff00},
6959        { 570,    110,     0.1,      2.0,        0x00ffff00},
6960        {  90,    300,     0.1,      2.0,        0x00ffff00},
6961        { 570,    300,     0.1,      2.0,        0x00ffff00}
6962     };
6963     D3DCAPS9 caps;
6964
6965     memset(&caps, 0, sizeof(caps));
6966     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6967     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6968
6969     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6970     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6971
6972     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6973     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6974     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6975     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6976     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6977     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6978     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6979         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6980         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6981         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6982         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6983     } else {
6984         trace("D3DDTCAPS_UBYTE4N not supported\n");
6985         dcl_ubyte_2 = NULL;
6986         dcl_ubyte = NULL;
6987     }
6988     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6989     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6990     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6991     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6992
6993     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6994     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6995                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6996     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6997
6998     hr = IDirect3DDevice9_BeginScene(device);
6999     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7000     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7001     if(SUCCEEDED(hr)) {
7002         if(dcl_color) {
7003             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7004             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7005             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7006             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7007         }
7008
7009         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7010          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7011          * using software vertex processing. Doh!
7012          */
7013         if(dcl_ubyte) {
7014             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7015             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7016             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7017             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7018             ub_ok = SUCCEEDED(hr);
7019         }
7020
7021         if(dcl_short) {
7022             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7023             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7024             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7025             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7026             s_ok = SUCCEEDED(hr);
7027         }
7028
7029         if(dcl_float) {
7030             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7031             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7032             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7033             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7034             f_ok = SUCCEEDED(hr);
7035         }
7036
7037         hr = IDirect3DDevice9_EndScene(device);
7038         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7039     }
7040
7041     if(dcl_short) {
7042         color = getPixelColor(device, 480, 360);
7043         ok(color == 0x000000ff || !s_ok,
7044            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7045     }
7046     if(dcl_ubyte) {
7047         color = getPixelColor(device, 160, 120);
7048         ok(color == 0x0000ffff || !ub_ok,
7049            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7050     }
7051     if(dcl_color) {
7052         color = getPixelColor(device, 160, 360);
7053         ok(color == 0x00ffff00,
7054            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7055     }
7056     if(dcl_float) {
7057         color = getPixelColor(device, 480, 120);
7058         ok(color == 0x00ff0000 || !f_ok,
7059            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7060     }
7061     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7062
7063     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7064      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7065      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7066      * whether the immediate mode code works
7067      */
7068     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7069     hr = IDirect3DDevice9_BeginScene(device);
7070     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7071     if(SUCCEEDED(hr)) {
7072         if(dcl_color) {
7073             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7074             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7075             memcpy(data, quad1, sizeof(quad1));
7076             hr = IDirect3DVertexBuffer9_Unlock(vb);
7077             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7078             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7079             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7080             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7081             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7082             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7083             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7084         }
7085
7086         if(dcl_ubyte) {
7087             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7088             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7089             memcpy(data, quad2, sizeof(quad2));
7090             hr = IDirect3DVertexBuffer9_Unlock(vb);
7091             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7092             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7093             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7094             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7095             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7096             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7097             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7098                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7099             ub_ok = SUCCEEDED(hr);
7100         }
7101
7102         if(dcl_short) {
7103             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7104             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7105             memcpy(data, quad3, sizeof(quad3));
7106             hr = IDirect3DVertexBuffer9_Unlock(vb);
7107             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7108             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7109             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7110             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7111             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7112             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7113             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7114                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7115             s_ok = SUCCEEDED(hr);
7116         }
7117
7118         if(dcl_float) {
7119             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7120             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7121             memcpy(data, quad4, sizeof(quad4));
7122             hr = IDirect3DVertexBuffer9_Unlock(vb);
7123             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7124             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7125             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7126             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7127             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7128             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7129             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7130                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7131             f_ok = SUCCEEDED(hr);
7132         }
7133
7134         hr = IDirect3DDevice9_EndScene(device);
7135         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7136     }
7137
7138     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7139     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7140     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7141     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7142
7143     if(dcl_short) {
7144         color = getPixelColor(device, 480, 360);
7145         ok(color == 0x000000ff || !s_ok,
7146            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7147     }
7148     if(dcl_ubyte) {
7149         color = getPixelColor(device, 160, 120);
7150         ok(color == 0x0000ffff || !ub_ok,
7151            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7152     }
7153     if(dcl_color) {
7154         color = getPixelColor(device, 160, 360);
7155         ok(color == 0x00ffff00,
7156            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7157     }
7158     if(dcl_float) {
7159         color = getPixelColor(device, 480, 120);
7160         ok(color == 0x00ff0000 || !f_ok,
7161            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7162     }
7163     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7164
7165     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7166     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7167
7168     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7169     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7170     memcpy(data, quad_transformed, sizeof(quad_transformed));
7171     hr = IDirect3DVertexBuffer9_Unlock(vb);
7172     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7173
7174     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7175     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7176
7177     hr = IDirect3DDevice9_BeginScene(device);
7178     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7179     if(SUCCEEDED(hr)) {
7180         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7181         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7182         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7183         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7184
7185         hr = IDirect3DDevice9_EndScene(device);
7186         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7187     }
7188
7189     color = getPixelColor(device, 88, 108);
7190     ok(color == 0x000000ff,
7191        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7192     color = getPixelColor(device, 92, 108);
7193     ok(color == 0x000000ff,
7194        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7195     color = getPixelColor(device, 88, 112);
7196     ok(color == 0x000000ff,
7197        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7198     color = getPixelColor(device, 92, 112);
7199     ok(color == 0x00ffff00,
7200        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7201
7202     color = getPixelColor(device, 568, 108);
7203     ok(color == 0x000000ff,
7204        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7205     color = getPixelColor(device, 572, 108);
7206     ok(color == 0x000000ff,
7207        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7208     color = getPixelColor(device, 568, 112);
7209     ok(color == 0x00ffff00,
7210        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7211     color = getPixelColor(device, 572, 112);
7212     ok(color == 0x000000ff,
7213        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7214
7215     color = getPixelColor(device, 88, 298);
7216     ok(color == 0x000000ff,
7217        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7218     color = getPixelColor(device, 92, 298);
7219     ok(color == 0x00ffff00,
7220        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7221     color = getPixelColor(device, 88, 302);
7222     ok(color == 0x000000ff,
7223        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7224     color = getPixelColor(device, 92, 302);
7225     ok(color == 0x000000ff,
7226        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7227
7228     color = getPixelColor(device, 568, 298);
7229     ok(color == 0x00ffff00,
7230        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7231     color = getPixelColor(device, 572, 298);
7232     ok(color == 0x000000ff,
7233        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7234     color = getPixelColor(device, 568, 302);
7235     ok(color == 0x000000ff,
7236        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7237     color = getPixelColor(device, 572, 302);
7238     ok(color == 0x000000ff,
7239        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7240
7241     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7242
7243     /* This test is pointless without those two declarations: */
7244     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7245         skip("color-ubyte switching test declarations aren't supported\n");
7246         goto out;
7247     }
7248
7249     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7250     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7251     memcpy(data, quads, sizeof(quads));
7252     hr = IDirect3DVertexBuffer9_Unlock(vb);
7253     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7254     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7255                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7256     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7257     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7258     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7259     memcpy(data, colors, sizeof(colors));
7260     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7261     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7262
7263     for(i = 0; i < 2; i++) {
7264         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7265         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7266
7267         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7268         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7269         if(i == 0) {
7270             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7271         } else {
7272             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7273         }
7274         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7275
7276         hr = IDirect3DDevice9_BeginScene(device);
7277         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7278         ub_ok = FALSE;
7279         if(SUCCEEDED(hr)) {
7280             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7281             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7282             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7283             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7284                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7285             ub_ok = SUCCEEDED(hr);
7286
7287             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7288             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7289             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7290             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7291
7292             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7293             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7294             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7295             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7296                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7297             ub_ok = (SUCCEEDED(hr) && ub_ok);
7298
7299             hr = IDirect3DDevice9_EndScene(device);
7300             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7301         }
7302
7303         if(i == 0) {
7304             color = getPixelColor(device, 480, 360);
7305             ok(color == 0x00ff0000,
7306                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7307             color = getPixelColor(device, 160, 120);
7308             ok(color == 0x00ffffff,
7309                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7310             color = getPixelColor(device, 160, 360);
7311             ok(color == 0x000000ff || !ub_ok,
7312                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7313             color = getPixelColor(device, 480, 120);
7314             ok(color == 0x000000ff || !ub_ok,
7315                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7316         } else {
7317             color = getPixelColor(device, 480, 360);
7318             ok(color == 0x000000ff,
7319                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7320             color = getPixelColor(device, 160, 120);
7321             ok(color == 0x00ffffff,
7322                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7323             color = getPixelColor(device, 160, 360);
7324             ok(color == 0x00ff0000 || !ub_ok,
7325                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7326             color = getPixelColor(device, 480, 120);
7327             ok(color == 0x00ff0000 || !ub_ok,
7328                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7329         }
7330         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7331     }
7332
7333     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7334     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7335     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7336     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7337     IDirect3DVertexBuffer9_Release(vb2);
7338
7339     out:
7340     IDirect3DVertexBuffer9_Release(vb);
7341     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7342     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7343     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7344     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7345     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7346     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7347     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7348 }
7349
7350 struct vertex_float16color {
7351     float x, y, z;
7352     DWORD c1, c2;
7353 };
7354
7355 static void test_vshader_float16(IDirect3DDevice9 *device)
7356 {
7357     HRESULT hr;
7358     DWORD color;
7359     void *data;
7360     static const D3DVERTEXELEMENT9 decl_elements[] = {
7361         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7362         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7363         D3DDECL_END()
7364     };
7365     IDirect3DVertexDeclaration9 *vdecl = NULL;
7366     IDirect3DVertexBuffer9 *buffer = NULL;
7367     IDirect3DVertexShader9 *shader;
7368     DWORD shader_code[] = {
7369         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7370         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7371         0x90e40001, 0x0000ffff
7372     };
7373     struct vertex_float16color quad[] = {
7374         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7375         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7376         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7377         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7378
7379         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7380         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7381         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7382         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7383
7384         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7385         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7386         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7387         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7388
7389         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7390         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7391         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7392         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7393     };
7394
7395     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7396     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7397
7398     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7399     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7400     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7401     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7402     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7403     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7404
7405     hr = IDirect3DDevice9_BeginScene(device);
7406     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7407     if(SUCCEEDED(hr)) {
7408         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7409         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7410         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7411         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7412         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7413         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7414         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7415         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7416         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7417         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7418
7419         hr = IDirect3DDevice9_EndScene(device);
7420         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7421     }
7422     color = getPixelColor(device, 480, 360);
7423     ok(color == 0x00ff0000,
7424        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7425     color = getPixelColor(device, 160, 120);
7426     ok(color == 0x00000000,
7427        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7428     color = getPixelColor(device, 160, 360);
7429     ok(color == 0x0000ff00,
7430        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7431     color = getPixelColor(device, 480, 120);
7432     ok(color == 0x000000ff,
7433        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7434     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7435
7436     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7437     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7438
7439     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7440                                              D3DPOOL_MANAGED, &buffer, NULL);
7441     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7442     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7443     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7444     memcpy(data, quad, sizeof(quad));
7445     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7446     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7447     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7448     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7449
7450     hr = IDirect3DDevice9_BeginScene(device);
7451     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7452     if(SUCCEEDED(hr)) {
7453             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7454             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7455             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7456             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7457             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7458             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7459             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7460             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7461
7462             hr = IDirect3DDevice9_EndScene(device);
7463             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7464     }
7465
7466     color = getPixelColor(device, 480, 360);
7467     ok(color == 0x00ff0000,
7468        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7469     color = getPixelColor(device, 160, 120);
7470     ok(color == 0x00000000,
7471        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7472     color = getPixelColor(device, 160, 360);
7473     ok(color == 0x0000ff00,
7474        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7475     color = getPixelColor(device, 480, 120);
7476     ok(color == 0x000000ff,
7477        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7478     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7479
7480     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7481     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7482     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7483     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7484     IDirect3DDevice9_SetVertexShader(device, NULL);
7485     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7486
7487     IDirect3DVertexDeclaration9_Release(vdecl);
7488     IDirect3DVertexShader9_Release(shader);
7489     IDirect3DVertexBuffer9_Release(buffer);
7490 }
7491
7492 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7493 {
7494     D3DCAPS9 caps;
7495     IDirect3DTexture9 *texture;
7496     HRESULT hr;
7497     D3DLOCKED_RECT rect;
7498     unsigned int x, y;
7499     DWORD *dst, color;
7500     const float quad[] = {
7501         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7502          1.0,   -1.0,   0.1,    1.2,   -0.2,
7503         -1.0,    1.0,   0.1,   -0.2,    1.2,
7504          1.0,    1.0,   0.1,    1.2,    1.2
7505     };
7506     memset(&caps, 0, sizeof(caps));
7507
7508     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7509     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7510     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7511         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7512         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7513            "Card has conditional NP2 support without power of two restriction set\n");
7514         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7515         return;
7516     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7517         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7518         return;
7519     }
7520
7521     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7523
7524     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7525     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7526
7527     memset(&rect, 0, sizeof(rect));
7528     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7529     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7530     for(y = 0; y < 10; y++) {
7531         for(x = 0; x < 10; x++) {
7532             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7533             if(x == 0 || x == 9 || y == 0 || y == 9) {
7534                 *dst = 0x00ff0000;
7535             } else {
7536                 *dst = 0x000000ff;
7537             }
7538         }
7539     }
7540     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7541     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7542
7543     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7544     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7545     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7546     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7547     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7548     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7549     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7550     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7551
7552     hr = IDirect3DDevice9_BeginScene(device);
7553     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7554     if(SUCCEEDED(hr)) {
7555         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7556         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7557
7558         hr = IDirect3DDevice9_EndScene(device);
7559         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7560     }
7561
7562     color = getPixelColor(device,    1,  1);
7563     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7564     color = getPixelColor(device, 639, 479);
7565     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7566
7567     color = getPixelColor(device, 135, 101);
7568     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7569     color = getPixelColor(device, 140, 101);
7570     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7571     color = getPixelColor(device, 135, 105);
7572     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7573     color = getPixelColor(device, 140, 105);
7574     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7575
7576     color = getPixelColor(device, 135, 376);
7577     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7578     color = getPixelColor(device, 140, 376);
7579     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7580     color = getPixelColor(device, 135, 379);
7581     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7582     color = getPixelColor(device, 140, 379);
7583     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7584
7585     color = getPixelColor(device, 500, 101);
7586     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7587     color = getPixelColor(device, 504, 101);
7588     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7589     color = getPixelColor(device, 500, 105);
7590     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7591     color = getPixelColor(device, 504, 105);
7592     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7593
7594     color = getPixelColor(device, 500, 376);
7595     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7596     color = getPixelColor(device, 504, 376);
7597     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7598     color = getPixelColor(device, 500, 380);
7599     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7600     color = getPixelColor(device, 504, 380);
7601     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7602
7603     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7604
7605     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7606     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7607     IDirect3DTexture9_Release(texture);
7608 }
7609
7610 static void vFace_register_test(IDirect3DDevice9 *device)
7611 {
7612     HRESULT hr;
7613     DWORD color;
7614     const DWORD shader_code[] = {
7615         0xffff0300,                                                             /* ps_3_0                     */
7616         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7617         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7618         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7619         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7620         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7621         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7622         0x0000ffff                                                              /* END                        */
7623     };
7624     const DWORD vshader_code[] = {
7625         0xfffe0300,                                                             /* vs_3_0               */
7626         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7627         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7628         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7629         0x0000ffff                                                              /* end                  */
7630     };
7631     IDirect3DPixelShader9 *shader;
7632     IDirect3DVertexShader9 *vshader;
7633     IDirect3DTexture9 *texture;
7634     IDirect3DSurface9 *surface, *backbuffer;
7635     const float quad[] = {
7636         -1.0,   -1.0,   0.1,
7637          1.0,   -1.0,   0.1,
7638         -1.0,    0.0,   0.1,
7639
7640          1.0,   -1.0,   0.1,
7641          1.0,    0.0,   0.1,
7642         -1.0,    0.0,   0.1,
7643
7644         -1.0,    0.0,   0.1,
7645         -1.0,    1.0,   0.1,
7646          1.0,    0.0,   0.1,
7647
7648          1.0,    0.0,   0.1,
7649         -1.0,    1.0,   0.1,
7650          1.0,    1.0,   0.1,
7651     };
7652     const float blit[] = {
7653          0.0,   -1.0,   0.1,    0.0,    0.0,
7654          1.0,   -1.0,   0.1,    1.0,    0.0,
7655          0.0,    1.0,   0.1,    0.0,    1.0,
7656          1.0,    1.0,   0.1,    1.0,    1.0,
7657     };
7658
7659     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7660     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7661     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7662     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7663     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7664     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7665     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7666     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7667     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7668     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7669     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7670     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7671     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7672     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7673     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7674     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7675
7676     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7677     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7678
7679     hr = IDirect3DDevice9_BeginScene(device);
7680     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7681     if(SUCCEEDED(hr)) {
7682         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7683         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7684         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7685         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7686         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7687         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7688         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7689         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7690         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7691         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7692         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7693
7694         /* Blit the texture onto the back buffer to make it visible */
7695         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7696         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7697         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7698         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7699         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7700         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7701         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7702         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7703         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7704         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7705         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7706         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7707
7708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7709         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7710
7711         hr = IDirect3DDevice9_EndScene(device);
7712         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7713     }
7714
7715     color = getPixelColor(device, 160, 360);
7716     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7717     color = getPixelColor(device, 160, 120);
7718     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7719     color = getPixelColor(device, 480, 360);
7720     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7721     color = getPixelColor(device, 480, 120);
7722     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7723     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7724
7725     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7726     IDirect3DDevice9_SetTexture(device, 0, NULL);
7727     IDirect3DPixelShader9_Release(shader);
7728     IDirect3DVertexShader9_Release(vshader);
7729     IDirect3DSurface9_Release(surface);
7730     IDirect3DSurface9_Release(backbuffer);
7731     IDirect3DTexture9_Release(texture);
7732 }
7733
7734 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7735 {
7736     HRESULT hr;
7737     DWORD color;
7738     int i;
7739     D3DCAPS9 caps;
7740     BOOL L6V5U5_supported = FALSE;
7741     IDirect3DTexture9 *tex1, *tex2;
7742     D3DLOCKED_RECT locked_rect;
7743
7744     static const float quad[][7] = {
7745         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7746         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7747         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7748         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7749     };
7750
7751     static const D3DVERTEXELEMENT9 decl_elements[] = {
7752         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7753         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7754         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7755         D3DDECL_END()
7756     };
7757
7758     /* use asymmetric matrix to test loading */
7759     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7760     float scale, offset;
7761
7762     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7763     IDirect3DTexture9           *texture            = NULL;
7764
7765     memset(&caps, 0, sizeof(caps));
7766     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7767     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7768     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7769         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7770         return;
7771     } else {
7772         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7773          * They report that it is not supported, but after that bump mapping works properly. So just test
7774          * if the format is generally supported, and check the BUMPENVMAP flag
7775          */
7776         IDirect3D9 *d3d9;
7777
7778         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7779         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7780                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7781         L6V5U5_supported = SUCCEEDED(hr);
7782         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7783                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7784         IDirect3D9_Release(d3d9);
7785         if(FAILED(hr)) {
7786             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7787             return;
7788         }
7789     }
7790
7791     /* Generate the textures */
7792     generate_bumpmap_textures(device);
7793
7794     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7795     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7796     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7797     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7798     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7799     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7800     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7801     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7802
7803     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7804     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7805     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7806     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7807     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7808     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7809
7810     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7811     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7812     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7813     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7815     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7816
7817     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7818     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7819
7820     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7821     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7822
7823     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7824     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7825
7826
7827     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7828     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7829     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7830     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7831
7832     hr = IDirect3DDevice9_BeginScene(device);
7833     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7834
7835     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7836     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7837
7838     hr = IDirect3DDevice9_EndScene(device);
7839     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7840
7841     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7842      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7843      * But since testing the color match is not the purpose of the test don't be too picky
7844      */
7845     color = getPixelColor(device, 320-32, 240);
7846     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7847     color = getPixelColor(device, 320+32, 240);
7848     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7849     color = getPixelColor(device, 320, 240-32);
7850     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7851     color = getPixelColor(device, 320, 240+32);
7852     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7853     color = getPixelColor(device, 320, 240);
7854     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7855     color = getPixelColor(device, 320+32, 240+32);
7856     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7857     color = getPixelColor(device, 320-32, 240+32);
7858     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7859     color = getPixelColor(device, 320+32, 240-32);
7860     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7861     color = getPixelColor(device, 320-32, 240-32);
7862     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7863     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7864     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7865
7866     for(i = 0; i < 2; i++) {
7867         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7868         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7869         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7870         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7871         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7872         IDirect3DTexture9_Release(texture); /* To destroy it */
7873     }
7874
7875     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7876         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7877         goto cleanup;
7878     }
7879     if(L6V5U5_supported == FALSE) {
7880         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7881         goto cleanup;
7882     }
7883
7884     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7885     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7886     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7887      * would only make this test more complicated
7888      */
7889     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7890     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7891     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7892     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7893
7894     memset(&locked_rect, 0, sizeof(locked_rect));
7895     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7896     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7897     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7898     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7899     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7900
7901     memset(&locked_rect, 0, sizeof(locked_rect));
7902     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7903     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7904     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7905     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7906     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7907
7908     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7909     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7910     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7911     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7912
7913     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7914     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7915     scale = 2.0;
7916     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7917     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7918     offset = 0.1;
7919     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7920     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7921
7922     hr = IDirect3DDevice9_BeginScene(device);
7923     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7924     if(SUCCEEDED(hr)) {
7925         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7926         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7927         hr = IDirect3DDevice9_EndScene(device);
7928         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7929     }
7930
7931     color = getPixelColor(device, 320, 240);
7932     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7933      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7934      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7935      */
7936     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7937     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7938     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7939
7940     /* Check a result scale factor > 1.0 */
7941     scale = 10;
7942     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7943     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7944     offset = 10;
7945     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7946     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7947
7948     hr = IDirect3DDevice9_BeginScene(device);
7949     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7950     if(SUCCEEDED(hr)) {
7951         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7952         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7953         hr = IDirect3DDevice9_EndScene(device);
7954         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7955     }
7956     color = getPixelColor(device, 320, 240);
7957     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7959     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7960
7961     /* Check clamping in the scale factor calculation */
7962     scale = 1000;
7963     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7964     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7965     offset = -1;
7966     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7967     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7968
7969     hr = IDirect3DDevice9_BeginScene(device);
7970     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7971     if(SUCCEEDED(hr)) {
7972         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7973         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7974         hr = IDirect3DDevice9_EndScene(device);
7975         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7976     }
7977     color = getPixelColor(device, 320, 240);
7978     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7979     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7980     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7981
7982     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7983     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7984     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7985     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7986
7987     IDirect3DTexture9_Release(tex1);
7988     IDirect3DTexture9_Release(tex2);
7989
7990 cleanup:
7991     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7992     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7993     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7994     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7995
7996     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7997     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7998     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7999 }
8000
8001 static void stencil_cull_test(IDirect3DDevice9 *device) {
8002     HRESULT hr;
8003     IDirect3DSurface9 *depthstencil = NULL;
8004     D3DSURFACE_DESC desc;
8005     float quad1[] = {
8006         -1.0,   -1.0,   0.1,
8007          0.0,   -1.0,   0.1,
8008         -1.0,    0.0,   0.1,
8009          0.0,    0.0,   0.1,
8010     };
8011     float quad2[] = {
8012          0.0,   -1.0,   0.1,
8013          1.0,   -1.0,   0.1,
8014          0.0,    0.0,   0.1,
8015          1.0,    0.0,   0.1,
8016     };
8017     float quad3[] = {
8018         0.0,    0.0,   0.1,
8019         1.0,    0.0,   0.1,
8020         0.0,    1.0,   0.1,
8021         1.0,    1.0,   0.1,
8022     };
8023     float quad4[] = {
8024         -1.0,    0.0,   0.1,
8025          0.0,    0.0,   0.1,
8026         -1.0,    1.0,   0.1,
8027          0.0,    1.0,   0.1,
8028     };
8029     struct vertex painter[] = {
8030        {-1.0,   -1.0,   0.0,    0x00000000},
8031        { 1.0,   -1.0,   0.0,    0x00000000},
8032        {-1.0,    1.0,   0.0,    0x00000000},
8033        { 1.0,    1.0,   0.0,    0x00000000},
8034     };
8035     WORD indices_cw[]  = {0, 1, 3};
8036     WORD indices_ccw[] = {0, 2, 3};
8037     unsigned int i;
8038     DWORD color;
8039
8040     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8041     if(depthstencil == NULL) {
8042         skip("No depth stencil buffer\n");
8043         return;
8044     }
8045     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8046     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8047     IDirect3DSurface9_Release(depthstencil);
8048     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8049         skip("No 4 or 8 bit stencil surface\n");
8050         return;
8051     }
8052
8053     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8054     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8055     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8056
8057     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8058     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8059     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8060     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8061     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8062     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8063     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8064     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8065
8066     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8067     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8068     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8069     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8070     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8071     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8072
8073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8074     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8076     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8077
8078     /* First pass: Fill the stencil buffer with some values... */
8079     hr = IDirect3DDevice9_BeginScene(device);
8080     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8081     if(SUCCEEDED(hr))
8082     {
8083         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8084         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8085         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8086                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8087         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8088         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8089                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8090         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8091
8092         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8093         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8094         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8095         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8096         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8097                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8098         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8099         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8100                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8101         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8102
8103         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8104         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8105         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8106                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8107         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8108         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8109                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8110         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8111
8112         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
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, quad4, 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, quad4, sizeof(float) * 3);
8119         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8120
8121         hr = IDirect3DDevice9_EndScene(device);
8122         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8123     }
8124
8125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8132     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8133     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8135     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8137     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8138
8139     /* 2nd pass: Make the stencil values visible */
8140     hr = IDirect3DDevice9_BeginScene(device);
8141     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8142     if(SUCCEEDED(hr))
8143     {
8144         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8145         for(i = 0; i < 16; i++) {
8146             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8147             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8148
8149             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8150             painter[1].diffuse = (i * 16);
8151             painter[2].diffuse = (i * 16);
8152             painter[3].diffuse = (i * 16);
8153             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8154             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8155         }
8156         hr = IDirect3DDevice9_EndScene(device);
8157         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8158     }
8159
8160     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8161     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8162
8163     color = getPixelColor(device, 160, 420);
8164     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8165     color = getPixelColor(device, 160, 300);
8166     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8167
8168     color = getPixelColor(device, 480, 420);
8169     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8170     color = getPixelColor(device, 480, 300);
8171     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8172
8173     color = getPixelColor(device, 160, 180);
8174     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8175     color = getPixelColor(device, 160, 60);
8176     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8177
8178     color = getPixelColor(device, 480, 180);
8179     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8180     color = getPixelColor(device, 480, 60);
8181     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8182
8183     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8184     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8185 }
8186
8187 static void vpos_register_test(IDirect3DDevice9 *device)
8188 {
8189     HRESULT hr;
8190     DWORD color;
8191     const DWORD shader_code[] = {
8192     0xffff0300,                                                             /* ps_3_0                     */
8193     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8194     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8195     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8196     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8197     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8198     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8199     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8200     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8201     0x0000ffff                                                              /* end                        */
8202     };
8203     const DWORD shader_frac_code[] = {
8204     0xffff0300,                                                             /* ps_3_0                     */
8205     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8206     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8207     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8208     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8209     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8210     0x0000ffff                                                              /* end                        */
8211     };
8212     const DWORD vshader_code[] = {
8213         0xfffe0300,                                                             /* vs_3_0               */
8214         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8215         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8216         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8217         0x0000ffff                                                              /* end                  */
8218     };
8219     IDirect3DVertexShader9 *vshader;
8220     IDirect3DPixelShader9 *shader, *shader_frac;
8221     IDirect3DSurface9 *surface = NULL, *backbuffer;
8222     const float quad[] = {
8223         -1.0,   -1.0,   0.1,    0.0,    0.0,
8224          1.0,   -1.0,   0.1,    1.0,    0.0,
8225         -1.0,    1.0,   0.1,    0.0,    1.0,
8226          1.0,    1.0,   0.1,    1.0,    1.0,
8227     };
8228     D3DLOCKED_RECT lr;
8229     float constant[4] = {1.0, 0.0, 320, 240};
8230     DWORD *pos;
8231
8232     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8233     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8234     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8235     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8236     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8237     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8238     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8239     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8240     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8241     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8242     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8243     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8244     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8245     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8246     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8247     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8248
8249     hr = IDirect3DDevice9_BeginScene(device);
8250     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8251     if(SUCCEEDED(hr)) {
8252         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8253         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8254         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8255         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8256         hr = IDirect3DDevice9_EndScene(device);
8257         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8258     }
8259
8260     /* This has to be pixel exact */
8261     color = getPixelColor(device, 319, 239);
8262     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8263     color = getPixelColor(device, 320, 239);
8264     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8265     color = getPixelColor(device, 319, 240);
8266     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8267     color = getPixelColor(device, 320, 240);
8268     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8269     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8270
8271     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8272                                              &surface, NULL);
8273     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8274     hr = IDirect3DDevice9_BeginScene(device);
8275     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8276     if(SUCCEEDED(hr)) {
8277         constant[2] = 16; constant[3] = 16;
8278         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8279         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8280         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8281         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8283         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8284         hr = IDirect3DDevice9_EndScene(device);
8285         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8286     }
8287     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8288     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8289
8290     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8291     color = *pos & 0x00ffffff;
8292     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8293     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8294     color = *pos & 0x00ffffff;
8295     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8296     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8297     color = *pos & 0x00ffffff;
8298     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8299     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8300     color = *pos & 0x00ffffff;
8301     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8302
8303     hr = IDirect3DSurface9_UnlockRect(surface);
8304     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8305
8306     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8307      * have full control over the multisampling setting inside this test
8308      */
8309     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8310     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8311     hr = IDirect3DDevice9_BeginScene(device);
8312     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8313     if(SUCCEEDED(hr)) {
8314         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8315         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8317         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8318         hr = IDirect3DDevice9_EndScene(device);
8319         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8320     }
8321     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8322     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8323
8324     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8325     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8326
8327     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8328     color = *pos & 0x00ffffff;
8329     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8330
8331     hr = IDirect3DSurface9_UnlockRect(surface);
8332     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8333
8334     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8335     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8336     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8337     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8338     IDirect3DPixelShader9_Release(shader);
8339     IDirect3DPixelShader9_Release(shader_frac);
8340     IDirect3DVertexShader9_Release(vshader);
8341     if(surface) IDirect3DSurface9_Release(surface);
8342     IDirect3DSurface9_Release(backbuffer);
8343 }
8344
8345 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8346 {
8347     D3DCOLOR color;
8348
8349     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8350     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8351     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8352     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8353     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8354
8355     ++r;
8356     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8357     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8358     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8359     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8360     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8361
8362     return TRUE;
8363 }
8364
8365 static void pointsize_test(IDirect3DDevice9 *device)
8366 {
8367     HRESULT hr;
8368     D3DCAPS9 caps;
8369     D3DMATRIX matrix;
8370     D3DMATRIX identity;
8371     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8372     DWORD color;
8373     IDirect3DSurface9 *rt, *backbuffer;
8374     IDirect3DTexture9 *tex1, *tex2;
8375     RECT rect = {0, 0, 128, 128};
8376     D3DLOCKED_RECT lr;
8377     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8378                                 0x00000000, 0x00000000};
8379     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8380                                 0x00000000, 0x0000ff00};
8381
8382     const float vertices[] = {
8383         64,     64,     0.1,
8384         128,    64,     0.1,
8385         192,    64,     0.1,
8386         256,    64,     0.1,
8387         320,    64,     0.1,
8388         384,    64,     0.1,
8389         448,    64,     0.1,
8390         512,    64,     0.1,
8391     };
8392
8393     /* 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 */
8394     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;
8395     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;
8396     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;
8397     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;
8398
8399     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;
8400     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;
8401     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;
8402     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;
8403
8404     memset(&caps, 0, sizeof(caps));
8405     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8406     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8407     if(caps.MaxPointSize < 32.0) {
8408         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8409         return;
8410     }
8411
8412     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8413     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8414     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8415     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8416     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8417     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8418     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8419     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8420
8421     hr = IDirect3DDevice9_BeginScene(device);
8422     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8423     if (SUCCEEDED(hr))
8424     {
8425         ptsize = 15.0;
8426         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8427         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8428         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8429         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8430
8431         ptsize = 31.0;
8432         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8433         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8436
8437         ptsize = 30.75;
8438         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8439         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8440         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8441         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8442
8443         if (caps.MaxPointSize >= 63.0)
8444         {
8445             ptsize = 63.0;
8446             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8447             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8448             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8449             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8450
8451             ptsize = 62.75;
8452             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8453             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8454             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8455             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8456         }
8457
8458         ptsize = 1.0;
8459         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8460         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8461         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8462         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8463
8464         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8465         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8466         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8467         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8468
8469         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8470         ptsize = 15.0;
8471         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8472         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8473         ptsize = 1.0;
8474         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8475         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8476         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8477         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8478
8479         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8480         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8481
8482         /* pointsize < pointsize_min < pointsize_max?
8483          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8484         ptsize = 1.0;
8485         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8486         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8487         ptsize = 15.0;
8488         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8489         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8490         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8491         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8492
8493         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8494         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8495
8496         hr = IDirect3DDevice9_EndScene(device);
8497         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8498     }
8499
8500     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8501     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8502     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8503
8504     if (caps.MaxPointSize >= 63.0)
8505     {
8506         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8507         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8508     }
8509
8510     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8511     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8512     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8513     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8514     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8515
8516     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8517
8518     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8519      * generates texture coordinates for the point(result: Yes, it does)
8520      *
8521      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8522      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8523      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8524      */
8525     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8526     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8527
8528     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8529     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8530     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8531     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8532     memset(&lr, 0, sizeof(lr));
8533     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8534     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8535     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8536     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8537     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8538     memset(&lr, 0, sizeof(lr));
8539     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8540     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8541     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8542     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8543     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8544     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8546     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8547     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8548     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8549     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8550     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8551     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8552     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8553     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8554     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8555     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8556     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8557     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8558
8559     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8560     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8561     ptsize = 32.0;
8562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8563     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8564
8565     hr = IDirect3DDevice9_BeginScene(device);
8566     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8567     if(SUCCEEDED(hr))
8568     {
8569         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8570         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8571         hr = IDirect3DDevice9_EndScene(device);
8572         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8573     }
8574
8575     color = getPixelColor(device, 64-4, 64-4);
8576     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8577     color = getPixelColor(device, 64-4, 64+4);
8578     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8579     color = getPixelColor(device, 64+4, 64+4);
8580     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8581     color = getPixelColor(device, 64+4, 64-4);
8582     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8583     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8584
8585     U(matrix).m[0][0] =  1.0f / 64.0f;
8586     U(matrix).m[1][1] = -1.0f / 64.0f;
8587     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8588     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8589
8590     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8591     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8592
8593     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8594             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8595     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8596
8597     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8598     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8599     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8600     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8601
8602     hr = IDirect3DDevice9_BeginScene(device);
8603     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8604     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8605     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8606     hr = IDirect3DDevice9_EndScene(device);
8607     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8608
8609     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8610     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8611     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8612     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8613     IDirect3DSurface9_Release(backbuffer);
8614     IDirect3DSurface9_Release(rt);
8615
8616     color = getPixelColor(device, 64-4, 64-4);
8617     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8618             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8619     color = getPixelColor(device, 64+4, 64-4);
8620     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8621             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8622     color = getPixelColor(device, 64-4, 64+4);
8623     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8624             "Expected color 0x00000000, got 0x%08x.\n", color);
8625     color = getPixelColor(device, 64+4, 64+4);
8626     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8627             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8628
8629     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8630     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8631
8632     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8633     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8634     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8635     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8636     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8637     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8638     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8639     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8640     IDirect3DTexture9_Release(tex1);
8641     IDirect3DTexture9_Release(tex2);
8642
8643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8644     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8645     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8646     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8647     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8648     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8649 }
8650
8651 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8652 {
8653     static const DWORD vshader_code[] =
8654     {
8655         0xfffe0300,                                                             /* vs_3_0                     */
8656         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8657         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8658         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8659         0x0000ffff                                                              /* end                        */
8660     };
8661     static const DWORD pshader_code[] =
8662     {
8663         0xffff0300,                                                             /* ps_3_0                     */
8664         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8665         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8666         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8667         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8668         0x0000ffff                                                              /* end                        */
8669     };
8670
8671     HRESULT hr;
8672     IDirect3DVertexShader9 *vs;
8673     IDirect3DPixelShader9 *ps;
8674     IDirect3DTexture9 *tex1, *tex2;
8675     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8676     D3DCAPS9 caps;
8677     DWORD color;
8678     float quad[] = {
8679        -1.0,   -1.0,    0.1,
8680         1.0,   -1.0,    0.1,
8681        -1.0,    1.0,    0.1,
8682         1.0,    1.0,    0.1,
8683     };
8684     float texquad[] = {
8685        -1.0,   -1.0,    0.1,    0.0,    0.0,
8686         0.0,   -1.0,    0.1,    1.0,    0.0,
8687        -1.0,    1.0,    0.1,    0.0,    1.0,
8688         0.0,    1.0,    0.1,    1.0,    1.0,
8689
8690         0.0,   -1.0,    0.1,    0.0,    0.0,
8691         1.0,   -1.0,    0.1,    1.0,    0.0,
8692         0.0,    1.0,    0.1,    0.0,    1.0,
8693         1.0,    1.0,    0.1,    1.0,    1.0,
8694     };
8695
8696     memset(&caps, 0, sizeof(caps));
8697     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8698     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8699     if(caps.NumSimultaneousRTs < 2) {
8700         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8701         return;
8702     }
8703
8704     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8705     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8706
8707     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8708             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8709     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8710
8711     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8712             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8713     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8714     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8715             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8716     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8717     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8718     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8719     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
8720     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8721
8722     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8723     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8724     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8725     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8726     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8727     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8728
8729     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8730     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8731     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8732     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8733     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8734     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8735     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8736     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8737     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8738     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8739
8740     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8741     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8742     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8743     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8744     color = getPixelColorFromSurface(readback, 8, 8);
8745     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8746             "Expected color 0x000000ff, got 0x%08x.\n", color);
8747     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8748     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8749     color = getPixelColorFromSurface(readback, 8, 8);
8750     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8751             "Expected color 0x000000ff, got 0x%08x.\n", color);
8752
8753     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8754     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8755     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8756     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8757     color = getPixelColorFromSurface(readback, 8, 8);
8758     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8759             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8760     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, 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, 0xff, 0x00), 0),
8764             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8765
8766     hr = IDirect3DDevice9_BeginScene(device);
8767     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8768     if(SUCCEEDED(hr)) {
8769         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8770         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8771
8772         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8773         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8774         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8775         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8776         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8777         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8778         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8779         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8780         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8781         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8782
8783         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8784         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8786         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8787
8788         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8789         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8791         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8792
8793         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8794         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8795
8796         hr = IDirect3DDevice9_EndScene(device);
8797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8798     }
8799
8800     color = getPixelColor(device, 160, 240);
8801     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8802     color = getPixelColor(device, 480, 240);
8803     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8804     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8805
8806     IDirect3DPixelShader9_Release(ps);
8807     IDirect3DVertexShader9_Release(vs);
8808     IDirect3DTexture9_Release(tex1);
8809     IDirect3DTexture9_Release(tex2);
8810     IDirect3DSurface9_Release(surf1);
8811     IDirect3DSurface9_Release(surf2);
8812     IDirect3DSurface9_Release(backbuf);
8813     IDirect3DSurface9_Release(readback);
8814 }
8815
8816 struct formats {
8817     const char *fmtName;
8818     D3DFORMAT textureFormat;
8819     DWORD resultColorBlending;
8820     DWORD resultColorNoBlending;
8821 };
8822
8823 static const struct formats test_formats[] = {
8824   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8825   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8826   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8827   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8828   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8829   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8830   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8831   { NULL, 0 }
8832 };
8833
8834 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8835 {
8836     HRESULT hr;
8837     IDirect3DTexture9 *offscreenTexture = NULL;
8838     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8839     IDirect3D9 *d3d = NULL;
8840     DWORD color;
8841     DWORD r0, g0, b0, r1, g1, b1;
8842     int fmt_index;
8843
8844     static const float quad[][5] = {
8845         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8846         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8847         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8848         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8849     };
8850
8851     /* Quad with R=0x10, G=0x20 */
8852     static const struct vertex quad1[] = {
8853         {-1.0f, -1.0f, 0.1f, 0x80102000},
8854         {-1.0f,  1.0f, 0.1f, 0x80102000},
8855         { 1.0f, -1.0f, 0.1f, 0x80102000},
8856         { 1.0f,  1.0f, 0.1f, 0x80102000},
8857     };
8858
8859     /* Quad with R=0x20, G=0x10 */
8860     static const struct vertex quad2[] = {
8861         {-1.0f, -1.0f, 0.1f, 0x80201000},
8862         {-1.0f,  1.0f, 0.1f, 0x80201000},
8863         { 1.0f, -1.0f, 0.1f, 0x80201000},
8864         { 1.0f,  1.0f, 0.1f, 0x80201000},
8865     };
8866
8867     IDirect3DDevice9_GetDirect3D(device, &d3d);
8868
8869     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8870     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8871     if(!backbuffer) {
8872         goto out;
8873     }
8874
8875     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8876     {
8877         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8878         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8879            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8880            continue;
8881         }
8882
8883         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8884         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8885
8886         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8887         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8888         if(!offscreenTexture) {
8889             continue;
8890         }
8891
8892         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8893         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8894         if(!offscreen) {
8895             continue;
8896         }
8897
8898         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8899         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8900
8901         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8902         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8903         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8904         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8905         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8906         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8907         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8908         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8909         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8910         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8911
8912         /* Below we will draw two quads with different colors and try to blend them together.
8913          * The result color is compared with the expected outcome.
8914          */
8915         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8916             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8917             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8918             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8919             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8920
8921             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8922             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8923
8924             /* Draw a quad using color 0x0010200 */
8925             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8926             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8927             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8928             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8929             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8930             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8931
8932             /* Draw a quad using color 0x0020100 */
8933             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8934             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8935             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8936             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8937             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8938             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8939
8940             /* We don't want to blend the result on the backbuffer */
8941             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8942             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8943
8944             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8945             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8946             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8947             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8948             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8949
8950             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8951             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8952
8953             /* This time with the texture */
8954             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8955             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8956
8957             IDirect3DDevice9_EndScene(device);
8958         }
8959
8960         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8961             /* Compare the color of the center quad with our expectation */
8962             color = getPixelColor(device, 320, 240);
8963             r0 = (color & 0x00ff0000) >> 16;
8964             g0 = (color & 0x0000ff00) >>  8;
8965             b0 = (color & 0x000000ff) >>  0;
8966
8967             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8968             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8969             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8970
8971             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8972                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8973                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8974                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8975         } else {
8976             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8977              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8978              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8979             color = getPixelColor(device, 320, 240);
8980             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);
8981         }
8982         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8983
8984         IDirect3DDevice9_SetTexture(device, 0, NULL);
8985         if(offscreenTexture) {
8986             IDirect3DTexture9_Release(offscreenTexture);
8987         }
8988         if(offscreen) {
8989             IDirect3DSurface9_Release(offscreen);
8990         }
8991     }
8992
8993 out:
8994     /* restore things */
8995     if(backbuffer) {
8996         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8997         IDirect3DSurface9_Release(backbuffer);
8998     }
8999 }
9000
9001 static void tssargtemp_test(IDirect3DDevice9 *device)
9002 {
9003     HRESULT hr;
9004     DWORD color;
9005     static const struct vertex quad[] = {
9006         {-1.0,     -1.0,    0.1,    0x00ff0000},
9007         { 1.0,     -1.0,    0.1,    0x00ff0000},
9008         {-1.0,      1.0,    0.1,    0x00ff0000},
9009         { 1.0,      1.0,    0.1,    0x00ff0000}
9010     };
9011     D3DCAPS9 caps;
9012
9013     memset(&caps, 0, sizeof(caps));
9014     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9015     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9016     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9017         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9018         return;
9019     }
9020
9021     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9022     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9023
9024     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9025     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9026     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9027     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9028
9029     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9030     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9031     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9032     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9033     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9034     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9035
9036     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9037     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9038     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9039     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9040     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9041     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9042
9043     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9044     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9045
9046     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9047     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9048     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9050
9051     hr = IDirect3DDevice9_BeginScene(device);
9052     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9053     if(SUCCEEDED(hr)) {
9054         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9055         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9056         hr = IDirect3DDevice9_EndScene(device);
9057         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9058     }
9059     color = getPixelColor(device, 320, 240);
9060     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9061     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9062
9063     /* Set stage 1 back to default */
9064     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9065     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9066     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9067     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9068     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9069     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9070     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9071     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9072     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9073     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9074 }
9075
9076 struct testdata
9077 {
9078     DWORD idxVertex; /* number of instances in the first stream */
9079     DWORD idxColor; /* number of instances in the second stream */
9080     DWORD idxInstance; /* should be 1 ?? */
9081     DWORD color1; /* color 1 instance */
9082     DWORD color2; /* color 2 instance */
9083     DWORD color3; /* color 3 instance */
9084     DWORD color4; /* color 4 instance */
9085     WORD strVertex; /* specify which stream to use 0-2*/
9086     WORD strColor;
9087     WORD strInstance;
9088 };
9089
9090 static const struct testdata testcases[]=
9091 {
9092     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9093     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9094     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9095     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9096     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9097     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9098     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9099     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9100     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9101     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9102     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9103     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9104     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9105     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9106     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9107 /*
9108     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9109     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9110 */
9111 };
9112
9113 /* Drawing Indexed Geometry with instances*/
9114 static void stream_test(IDirect3DDevice9 *device)
9115 {
9116     IDirect3DVertexBuffer9 *vb = NULL;
9117     IDirect3DVertexBuffer9 *vb2 = NULL;
9118     IDirect3DVertexBuffer9 *vb3 = NULL;
9119     IDirect3DIndexBuffer9 *ib = NULL;
9120     IDirect3DVertexDeclaration9 *pDecl = NULL;
9121     IDirect3DVertexShader9 *shader = NULL;
9122     HRESULT hr;
9123     BYTE *data;
9124     DWORD color;
9125     DWORD ind;
9126     unsigned i;
9127
9128     const DWORD shader_code[] =
9129     {
9130         0xfffe0101,                                     /* vs_1_1 */
9131         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9132         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9133         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9134         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9135         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9136         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9137         0x0000ffff
9138     };
9139
9140     const float quad[][3] =
9141     {
9142         {-0.5f, -0.5f,  1.1f}, /*0 */
9143         {-0.5f,  0.5f,  1.1f}, /*1 */
9144         { 0.5f, -0.5f,  1.1f}, /*2 */
9145         { 0.5f,  0.5f,  1.1f}, /*3 */
9146     };
9147
9148     const float vertcolor[][4] =
9149     {
9150         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9151         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9152         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9153         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9154     };
9155
9156     /* 4 position for 4 instances */
9157     const float instancepos[][3] =
9158     {
9159         {-0.6f,-0.6f, 0.0f},
9160         { 0.6f,-0.6f, 0.0f},
9161         { 0.6f, 0.6f, 0.0f},
9162         {-0.6f, 0.6f, 0.0f},
9163     };
9164
9165     short indices[] = {0, 1, 2, 1, 2, 3};
9166
9167     D3DVERTEXELEMENT9 decl[] =
9168     {
9169         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9170         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9171         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9172         D3DDECL_END()
9173     };
9174
9175     /* set the default value because it isn't done in wine? */
9176     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9177     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9178
9179     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9180     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9181     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9182
9183     /* check wrong cases */
9184     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9185     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9186     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9187     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9188     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9189     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9190     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9191     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9192     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9193     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9194     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9195     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9196     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9197     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9198     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9199     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9200     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9201     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9202     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9203     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9204
9205     /* set the default value back */
9206     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9207     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9208
9209     /* create all VertexBuffers*/
9210     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9211     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9212     if(!vb) {
9213         skip("Failed to create a vertex buffer\n");
9214         return;
9215     }
9216     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9217     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9218     if(!vb2) {
9219         skip("Failed to create a vertex buffer\n");
9220         goto out;
9221     }
9222     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9223     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9224     if(!vb3) {
9225         skip("Failed to create a vertex buffer\n");
9226         goto out;
9227     }
9228
9229     /* create IndexBuffer*/
9230     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9231     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9232     if(!ib) {
9233         skip("Failed to create a index buffer\n");
9234         goto out;
9235     }
9236
9237     /* copy all Buffers (Vertex + Index)*/
9238     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9239     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9240     memcpy(data, quad, sizeof(quad));
9241     hr = IDirect3DVertexBuffer9_Unlock(vb);
9242     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9243     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9244     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9245     memcpy(data, vertcolor, sizeof(vertcolor));
9246     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9247     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9248     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9249     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9250     memcpy(data, instancepos, sizeof(instancepos));
9251     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9252     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9253     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9254     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9255     memcpy(data, indices, sizeof(indices));
9256     hr = IDirect3DIndexBuffer9_Unlock(ib);
9257     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9258
9259     /* create VertexShader */
9260     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9261     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9262     if(!shader) {
9263         skip("Failed to create a vetex shader\n");
9264         goto out;
9265     }
9266
9267     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9268     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9269
9270     hr = IDirect3DDevice9_SetIndices(device, ib);
9271     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9272
9273     /* run all tests */
9274     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9275     {
9276         struct testdata act = testcases[i];
9277         decl[0].Stream = act.strVertex;
9278         decl[1].Stream = act.strColor;
9279         decl[2].Stream = act.strInstance;
9280         /* create VertexDeclarations */
9281         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9282         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9283
9284         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9285         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9286
9287         hr = IDirect3DDevice9_BeginScene(device);
9288         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9289         if(SUCCEEDED(hr))
9290         {
9291             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9292             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9293
9294             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9295             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9296             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9297             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9298
9299             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9300             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9301             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9302             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9303
9304             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9305             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9306             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9307             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9308
9309             /* don't know if this is right (1*3 and 4*1)*/
9310             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9311             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9312             hr = IDirect3DDevice9_EndScene(device);
9313             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9314
9315             /* set all StreamSource && StreamSourceFreq back to default */
9316             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9317             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9318             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9319             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9320             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9321             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9322             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9323             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9324             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9325             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9326             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9327             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9328         }
9329
9330         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9331         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9332
9333         color = getPixelColor(device, 160, 360);
9334         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9335         color = getPixelColor(device, 480, 360);
9336         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9337         color = getPixelColor(device, 480, 120);
9338         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9339         color = getPixelColor(device, 160, 120);
9340         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9341
9342         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9343         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9344     }
9345
9346     hr = IDirect3DDevice9_SetIndices(device, NULL);
9347     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9348
9349 out:
9350     if(vb) IDirect3DVertexBuffer9_Release(vb);
9351     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9352     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9353     if(ib)IDirect3DIndexBuffer9_Release(ib);
9354     if(shader)IDirect3DVertexShader9_Release(shader);
9355 }
9356
9357 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9358     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9359     IDirect3DTexture9 *dsttex = NULL;
9360     HRESULT hr;
9361     DWORD color;
9362     D3DRECT r1 = {0,  0,  50,  50 };
9363     D3DRECT r2 = {50, 0,  100, 50 };
9364     D3DRECT r3 = {50, 50, 100, 100};
9365     D3DRECT r4 = {0,  50,  50, 100};
9366     const float quad[] = {
9367         -1.0,   -1.0,   0.1,    0.0,    0.0,
9368          1.0,   -1.0,   0.1,    1.0,    0.0,
9369         -1.0,    1.0,   0.1,    0.0,    1.0,
9370          1.0,    1.0,   0.1,    1.0,    1.0,
9371     };
9372
9373     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9374     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9375
9376     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9377     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9378     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9379     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9380
9381     if(!src || !dsttex) {
9382         skip("One or more test resources could not be created\n");
9383         goto cleanup;
9384     }
9385
9386     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9387     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9388
9389     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9390     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9391
9392     /* Clear the StretchRect destination for debugging */
9393     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9394     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9395     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9396     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9397
9398     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9399     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9400
9401     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9402     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9403     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9404     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9405     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9406     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9407     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9408     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9409
9410     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9411      * the target -> texture GL blit path
9412      */
9413     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9414     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9415     IDirect3DSurface9_Release(dst);
9416
9417     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9418     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9419
9420     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9422     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9423     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9424     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9425     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9426     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9427     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9428
9429     hr = IDirect3DDevice9_BeginScene(device);
9430     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9431     if(SUCCEEDED(hr)) {
9432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9433         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9434         hr = IDirect3DDevice9_EndScene(device);
9435         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9436     }
9437
9438     color = getPixelColor(device, 160, 360);
9439     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9440     color = getPixelColor(device, 480, 360);
9441     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9442     color = getPixelColor(device, 480, 120);
9443     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9444     color = getPixelColor(device, 160, 120);
9445     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9446     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9447     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9448
9449     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9450     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9451     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9452     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9453
9454 cleanup:
9455     if(src) IDirect3DSurface9_Release(src);
9456     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9457     if(dsttex) IDirect3DTexture9_Release(dsttex);
9458 }
9459
9460 static void texop_test(IDirect3DDevice9 *device)
9461 {
9462     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9463     IDirect3DTexture9 *texture = NULL;
9464     D3DLOCKED_RECT locked_rect;
9465     D3DCOLOR color;
9466     D3DCAPS9 caps;
9467     HRESULT hr;
9468     unsigned i;
9469
9470     static const struct {
9471         float x, y, z;
9472         float s, t;
9473         D3DCOLOR diffuse;
9474     } quad[] = {
9475         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9476         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9477         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9478         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9479     };
9480
9481     static const D3DVERTEXELEMENT9 decl_elements[] = {
9482         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9483         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9484         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9485         D3DDECL_END()
9486     };
9487
9488     static const struct {
9489         D3DTEXTUREOP op;
9490         const char *name;
9491         DWORD caps_flag;
9492         D3DCOLOR result;
9493     } test_data[] = {
9494         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9495         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9496         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9497         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9498         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9499         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9500         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9501         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9502         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9503         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9504         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9505         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9506         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9507         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9508         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9509         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9510         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9511         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9512         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9513         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9514         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9515         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9516         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9517     };
9518
9519     memset(&caps, 0, sizeof(caps));
9520     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9521     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9522
9523     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9524     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9525     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9526     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9527
9528     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9529     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9530     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9531     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9532     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9533     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9534     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9535     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9536     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9537
9538     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9539     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9540     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9541     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9542     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9543     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9544
9545     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9546     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9547
9548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9549     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9551     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9552     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9553     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9554
9555     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9556     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9557
9558     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9559     {
9560         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9561         {
9562             skip("tex operation %s not supported\n", test_data[i].name);
9563             continue;
9564         }
9565
9566         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9567         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9568
9569         hr = IDirect3DDevice9_BeginScene(device);
9570         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9571
9572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9573         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9574
9575         hr = IDirect3DDevice9_EndScene(device);
9576         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9577
9578         color = getPixelColor(device, 320, 240);
9579         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9580                 test_data[i].name, color, test_data[i].result);
9581
9582         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9583         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9584     }
9585
9586     if (texture) IDirect3DTexture9_Release(texture);
9587     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9588 }
9589
9590 static void yuv_color_test(IDirect3DDevice9 *device) {
9591     HRESULT hr;
9592     IDirect3DSurface9 *surface = NULL, *target = NULL;
9593     unsigned int fmt, i;
9594     D3DFORMAT format;
9595     const char *fmt_string;
9596     D3DLOCKED_RECT lr;
9597     IDirect3D9 *d3d;
9598     HRESULT color;
9599     DWORD ref_color_left, ref_color_right;
9600
9601     struct {
9602         DWORD in;           /* The input color */
9603         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9604         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9605         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9606         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9607     } test_data[] = {
9608     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9609      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9610      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9611      * that
9612      */
9613       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9614       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9615       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9616       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9617       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9618       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9619       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9620       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9621       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9622       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9623       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9624       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9625       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9626       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9627
9628       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9629       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9630       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9631       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9632     };
9633
9634     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9635     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9636     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9637     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9638
9639     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9640     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9641
9642     for(fmt = 0; fmt < 2; fmt++) {
9643         if(fmt == 0) {
9644             format = D3DFMT_UYVY;
9645             fmt_string = "D3DFMT_UYVY";
9646         } else {
9647             format = D3DFMT_YUY2;
9648             fmt_string = "D3DFMT_YUY2";
9649         }
9650
9651         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9652                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9653                        */
9654         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9655                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9656             skip("%s is not supported\n", fmt_string);
9657             continue;
9658         }
9659
9660         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9661         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9662         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9663
9664         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9665             if(fmt == 0) {
9666                 ref_color_left = test_data[i].uyvy_left;
9667                 ref_color_right = test_data[i].uyvy_right;
9668             } else {
9669                 ref_color_left = test_data[i].yuy2_left;
9670                 ref_color_right = test_data[i].yuy2_right;
9671             }
9672
9673             memset(&lr, 0, sizeof(lr));
9674             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9675             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9676             *((DWORD *) lr.pBits) = test_data[i].in;
9677             hr = IDirect3DSurface9_UnlockRect(surface);
9678             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9679
9680             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9681             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9682             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9683             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9684
9685             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9686              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9687              * want to add tests for the filtered pixels as well.
9688              *
9689              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9690              * differently, so we need a max diff of 16
9691              */
9692             color = getPixelColor(device, 40, 240);
9693             ok(color_match(color, ref_color_left, 18),
9694                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9695                test_data[i].in, color, ref_color_left, fmt_string);
9696             color = getPixelColor(device, 600, 240);
9697             ok(color_match(color, ref_color_right, 18),
9698                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9699                test_data[i].in, color, ref_color_right, fmt_string);
9700             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9701             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9702         }
9703         IDirect3DSurface9_Release(surface);
9704     }
9705     IDirect3DSurface9_Release(target);
9706     IDirect3D9_Release(d3d);
9707 }
9708
9709 static void texop_range_test(IDirect3DDevice9 *device)
9710 {
9711     static const struct {
9712         float x, y, z;
9713         D3DCOLOR diffuse;
9714     } quad[] = {
9715         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9716         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9717         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9718         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9719     };
9720     HRESULT hr;
9721     IDirect3DTexture9 *texture;
9722     D3DLOCKED_RECT locked_rect;
9723     D3DCAPS9 caps;
9724     DWORD color;
9725
9726     /* We need ADD and SUBTRACT operations */
9727     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9728     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9729     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9730         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9731         return;
9732     }
9733     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9734         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9735         return;
9736     }
9737
9738     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9739     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9740     /* Stage 1: result = diffuse(=1.0) + diffuse
9741      * stage 2: result = result - tfactor(= 0.5)
9742      */
9743     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9744     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9745     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9746     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9747     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9748     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9749     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9750     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9751     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9752     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9753     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9754     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9755     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9756     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9757
9758     hr = IDirect3DDevice9_BeginScene(device);
9759     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9760     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9761     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9762     hr = IDirect3DDevice9_EndScene(device);
9763     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9764
9765     color = getPixelColor(device, 320, 240);
9766     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9767        color);
9768     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9769     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9770
9771     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9772     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9773     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9774     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9775     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9776     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9777     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9778     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9779     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9780
9781     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9782      * stage 2: result = result + diffuse(1.0)
9783      */
9784     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9785     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9786     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9787     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9788     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9789     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9790     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9791     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9792     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9793     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9794     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9795     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9796     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9797     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9798
9799     hr = IDirect3DDevice9_BeginScene(device);
9800     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9801     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9802     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9803     hr = IDirect3DDevice9_EndScene(device);
9804     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9805
9806     color = getPixelColor(device, 320, 240);
9807     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9808        color);
9809     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9810     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9811
9812     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9813     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9814     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9815     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9816     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9817     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9818     IDirect3DTexture9_Release(texture);
9819 }
9820
9821 static void alphareplicate_test(IDirect3DDevice9 *device) {
9822     struct vertex quad[] = {
9823         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9824         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9825         { -1.0,     1.0,    0.1,    0x80ff00ff },
9826         {  1.0,     1.0,    0.1,    0x80ff00ff },
9827     };
9828     HRESULT hr;
9829     DWORD color;
9830
9831     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9832     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9833
9834     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9835     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9836
9837     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9838     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9839     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9840     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9841
9842     hr = IDirect3DDevice9_BeginScene(device);
9843     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9844     if(SUCCEEDED(hr)) {
9845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9846         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9847         hr = IDirect3DDevice9_EndScene(device);
9848         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9849     }
9850
9851     color = getPixelColor(device, 320, 240);
9852     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9853        color);
9854     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9855     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9856
9857     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9858     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9859
9860 }
9861
9862 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9863     HRESULT hr;
9864     D3DCAPS9 caps;
9865     DWORD color;
9866     struct vertex quad[] = {
9867         { -1.0,    -1.0,    0.1,    0x408080c0 },
9868         {  1.0,    -1.0,    0.1,    0x408080c0 },
9869         { -1.0,     1.0,    0.1,    0x408080c0 },
9870         {  1.0,     1.0,    0.1,    0x408080c0 },
9871     };
9872
9873     memset(&caps, 0, sizeof(caps));
9874     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9875     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9876     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9877         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9878         return;
9879     }
9880
9881     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9882     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9883
9884     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9885     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9886
9887     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9888      * mov r0.a, diffuse.a
9889      * mov r0, r0.a
9890      *
9891      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9892      * 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
9893      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9894      */
9895     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9896     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9897     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9898     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9899     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9900     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9901     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9902     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9903     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9904     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9905     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9906     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9907     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9908     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9909     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9910     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9911     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9912     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9913
9914     hr = IDirect3DDevice9_BeginScene(device);
9915     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9916     if(SUCCEEDED(hr)) {
9917         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9918         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9919         hr = IDirect3DDevice9_EndScene(device);
9920         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9921     }
9922
9923     color = getPixelColor(device, 320, 240);
9924     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9925        color);
9926     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9927     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9928
9929     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9930     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9931     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9932     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9933     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9934     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9935 }
9936
9937 static void zwriteenable_test(IDirect3DDevice9 *device) {
9938     HRESULT hr;
9939     DWORD color;
9940     struct vertex quad1[] = {
9941         { -1.0,  -1.0,  0.1,    0x00ff0000},
9942         { -1.0,   1.0,  0.1,    0x00ff0000},
9943         {  1.0,  -1.0,  0.1,    0x00ff0000},
9944         {  1.0,   1.0,  0.1,    0x00ff0000},
9945     };
9946     struct vertex quad2[] = {
9947         { -1.0,  -1.0,  0.9,    0x0000ff00},
9948         { -1.0,   1.0,  0.9,    0x0000ff00},
9949         {  1.0,  -1.0,  0.9,    0x0000ff00},
9950         {  1.0,   1.0,  0.9,    0x0000ff00},
9951     };
9952
9953     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9954     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9955
9956     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9957     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9958     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9959     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9960     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9961     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9962     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9963     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9964
9965     hr = IDirect3DDevice9_BeginScene(device);
9966     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9967     if(SUCCEEDED(hr)) {
9968         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9969          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9970          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9971          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9972          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9973          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9974          */
9975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9976         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9977         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9978         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9980         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9981
9982         hr = IDirect3DDevice9_EndScene(device);
9983         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9984     }
9985
9986     color = getPixelColor(device, 320, 240);
9987     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9988        color);
9989     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9990     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9991
9992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9993     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9994 }
9995
9996 static void alphatest_test(IDirect3DDevice9 *device) {
9997 #define ALPHATEST_PASSED 0x0000ff00
9998 #define ALPHATEST_FAILED 0x00ff0000
9999     struct {
10000         D3DCMPFUNC  func;
10001         DWORD       color_less;
10002         DWORD       color_equal;
10003         DWORD       color_greater;
10004     } testdata[] = {
10005         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10006         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10007         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10008         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10009         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10010         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10011         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10012         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10013     };
10014     unsigned int i, j;
10015     HRESULT hr;
10016     DWORD color;
10017     struct vertex quad[] = {
10018         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10019         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10020         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10021         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10022     };
10023     D3DCAPS9 caps;
10024
10025     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10026     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10027     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10028     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10029
10030     for(j = 0; j < 2; j++) {
10031         if(j == 1) {
10032             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10033              * the alpha test either for performance reasons(floating point RTs) or to work
10034              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10035              * codepath for ffp and shader in this case, and the test should cover both
10036              */
10037             IDirect3DPixelShader9 *ps;
10038             DWORD shader_code[] = {
10039                 0xffff0101,                                 /* ps_1_1           */
10040                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10041                 0x0000ffff                                  /* end              */
10042             };
10043             memset(&caps, 0, sizeof(caps));
10044             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10045             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10046             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10047                 break;
10048             }
10049
10050             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10051             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10052             IDirect3DDevice9_SetPixelShader(device, ps);
10053             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10054             IDirect3DPixelShader9_Release(ps);
10055         }
10056
10057         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10058             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10059             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10060
10061             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10062             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10063             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10064             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10065             hr = IDirect3DDevice9_BeginScene(device);
10066             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10067             if(SUCCEEDED(hr)) {
10068                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10069                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10070                 hr = IDirect3DDevice9_EndScene(device);
10071                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10072             }
10073             color = getPixelColor(device, 320, 240);
10074             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10075             color, testdata[i].color_less, testdata[i].func);
10076             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10077             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10078
10079             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10080             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10081             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10082             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10083             hr = IDirect3DDevice9_BeginScene(device);
10084             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10085             if(SUCCEEDED(hr)) {
10086                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10087                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10088                 hr = IDirect3DDevice9_EndScene(device);
10089                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10090             }
10091             color = getPixelColor(device, 320, 240);
10092             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10093             color, testdata[i].color_equal, testdata[i].func);
10094             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10095             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10096
10097             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10098             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10099             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10100             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10101             hr = IDirect3DDevice9_BeginScene(device);
10102             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10103             if(SUCCEEDED(hr)) {
10104                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10105                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10106                 hr = IDirect3DDevice9_EndScene(device);
10107                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10108             }
10109             color = getPixelColor(device, 320, 240);
10110             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10111             color, testdata[i].color_greater, testdata[i].func);
10112             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10113             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10114         }
10115     }
10116
10117     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10118     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10119     IDirect3DDevice9_SetPixelShader(device, NULL);
10120     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10121 }
10122
10123 static void sincos_test(IDirect3DDevice9 *device) {
10124     const DWORD sin_shader_code[] = {
10125         0xfffe0200,                                                                 /* vs_2_0                       */
10126         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10127         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10128         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10129         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10130         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10131         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10132         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10133         0x0000ffff                                                                  /* end                          */
10134     };
10135     const DWORD cos_shader_code[] = {
10136         0xfffe0200,                                                                 /* vs_2_0                       */
10137         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10138         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10139         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10140         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10141         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10142         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10143         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10144         0x0000ffff                                                                  /* end                          */
10145     };
10146     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10147     HRESULT hr;
10148     struct {
10149         float x, y, z;
10150     } data[1280];
10151     unsigned int i;
10152     float sincosc1[4] = {D3DSINCOSCONST1};
10153     float sincosc2[4] = {D3DSINCOSCONST2};
10154
10155     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10156     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10157
10158     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10159     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10160     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10161     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10162     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10163     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10164     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10165     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10166     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10167     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10168
10169     /* Generate a point from -1 to 1 every 0.5 pixels */
10170     for(i = 0; i < 1280; i++) {
10171         data[i].x = (-640.0 + i) / 640.0;
10172         data[i].y = 0.0;
10173         data[i].z = 0.1;
10174     }
10175
10176     hr = IDirect3DDevice9_BeginScene(device);
10177     if(SUCCEEDED(hr)) {
10178         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10179         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10180         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10181         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10182
10183         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10184         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10186         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10187
10188         hr = IDirect3DDevice9_EndScene(device);
10189         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10190     }
10191     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10192     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10193     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10194
10195     IDirect3DDevice9_SetVertexShader(device, NULL);
10196     IDirect3DVertexShader9_Release(sin_shader);
10197     IDirect3DVertexShader9_Release(cos_shader);
10198 }
10199
10200 static void loop_index_test(IDirect3DDevice9 *device) {
10201     const DWORD shader_code[] = {
10202         0xfffe0200,                                                 /* vs_2_0                   */
10203         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10204         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10205         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10206         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10207         0x0000001d,                                                 /* endloop                  */
10208         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10209         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10210         0x0000ffff                                                  /* END                      */
10211     };
10212     IDirect3DVertexShader9 *shader;
10213     HRESULT hr;
10214     DWORD color;
10215     const float quad[] = {
10216         -1.0,   -1.0,   0.1,
10217          1.0,   -1.0,   0.1,
10218         -1.0,    1.0,   0.1,
10219          1.0,    1.0,   0.1
10220     };
10221     const float zero[4] = {0, 0, 0, 0};
10222     const float one[4] = {1, 1, 1, 1};
10223     int i0[4] = {2, 10, -3, 0};
10224     float values[4];
10225
10226     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10227     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10228     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10229     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10230     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10231     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10232     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10233     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10234
10235     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10236     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10237     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10238     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10239     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10240     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10241     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10242     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10243     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10244     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10245     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10246     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10247     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10248     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10249     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10250     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10251     values[0] = 1.0;
10252     values[1] = 1.0;
10253     values[2] = 0.0;
10254     values[3] = 0.0;
10255     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10256     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10257     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10258     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10259     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10260     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10261     values[0] = -1.0;
10262     values[1] = 0.0;
10263     values[2] = 0.0;
10264     values[3] = 0.0;
10265     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10266     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10267     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10268     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10269     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10270     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10271     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10272     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10273     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10274     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10275
10276     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10277     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10278
10279     hr = IDirect3DDevice9_BeginScene(device);
10280     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10281     if(SUCCEEDED(hr))
10282     {
10283         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10284         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10285         hr = IDirect3DDevice9_EndScene(device);
10286         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10287     }
10288     color = getPixelColor(device, 320, 240);
10289     ok(color_match(color, 0x0000ff00, 1),
10290        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10291     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10292     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10293
10294     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10295     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10296     IDirect3DVertexShader9_Release(shader);
10297 }
10298
10299 static void sgn_test(IDirect3DDevice9 *device) {
10300     const DWORD shader_code[] = {
10301         0xfffe0200,                                                             /* vs_2_0                       */
10302         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10303         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10304         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10305         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10306         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10307         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10308         0x0000ffff                                                              /* end                          */
10309     };
10310     IDirect3DVertexShader9 *shader;
10311     HRESULT hr;
10312     DWORD color;
10313     const float quad[] = {
10314         -1.0,   -1.0,   0.1,
10315          1.0,   -1.0,   0.1,
10316         -1.0,    1.0,   0.1,
10317          1.0,    1.0,   0.1
10318     };
10319
10320     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10321     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10322     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10323     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10324     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10325     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10326     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10327     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10328
10329     hr = IDirect3DDevice9_BeginScene(device);
10330     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10331     if(SUCCEEDED(hr))
10332     {
10333         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10334         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10335         hr = IDirect3DDevice9_EndScene(device);
10336         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10337     }
10338     color = getPixelColor(device, 320, 240);
10339     ok(color_match(color, 0x008000ff, 1),
10340        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10341     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10342     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10343
10344     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10345     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10346     IDirect3DVertexShader9_Release(shader);
10347 }
10348
10349 static void viewport_test(IDirect3DDevice9 *device) {
10350     HRESULT hr;
10351     DWORD color;
10352     D3DVIEWPORT9 vp, old_vp;
10353     BOOL draw_failed = TRUE;
10354     const float quad[] =
10355     {
10356         -0.5,   -0.5,   0.1,
10357          0.5,   -0.5,   0.1,
10358         -0.5,    0.5,   0.1,
10359          0.5,    0.5,   0.1
10360     };
10361
10362     memset(&old_vp, 0, sizeof(old_vp));
10363     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10364     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10365
10366     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10367     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10368
10369     /* Test a viewport with Width and Height bigger than the surface dimensions
10370      *
10371      * TODO: Test Width < surface.width, but X + Width > surface.width
10372      * TODO: Test Width < surface.width, what happens with the height?
10373      *
10374      * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10375      * and Height fields bigger than the framebuffer. However, it later refuses
10376      * to draw.
10377      */
10378     memset(&vp, 0, sizeof(vp));
10379     vp.X = 0;
10380     vp.Y = 0;
10381     vp.Width = 10000;
10382     vp.Height = 10000;
10383     vp.MinZ = 0.0;
10384     vp.MaxZ = 0.0;
10385     hr = IDirect3DDevice9_SetViewport(device, &vp);
10386     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10387
10388     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10389     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10390     hr = IDirect3DDevice9_BeginScene(device);
10391     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10392     if(SUCCEEDED(hr))
10393     {
10394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10395         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10396         draw_failed = FAILED(hr);
10397         hr = IDirect3DDevice9_EndScene(device);
10398         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10399     }
10400
10401     if(!draw_failed)
10402     {
10403         color = getPixelColor(device, 158, 118);
10404         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10405         color = getPixelColor(device, 162, 118);
10406         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10407         color = getPixelColor(device, 158, 122);
10408         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10409         color = getPixelColor(device, 162, 122);
10410         ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10411
10412         color = getPixelColor(device, 478, 358);
10413         ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10414         color = getPixelColor(device, 482, 358);
10415         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10416         color = getPixelColor(device, 478, 362);
10417         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10418         color = getPixelColor(device, 482, 362);
10419         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10420     }
10421
10422     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10423     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10424
10425     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10426     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10427 }
10428
10429 /* This test tests depth clamping / clipping behaviour:
10430  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10431  *   minimum/maximum z value.
10432  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10433  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10434  *   - Pretransformed vertices behave the same as regular vertices.
10435  */
10436 static void depth_clamp_test(IDirect3DDevice9 *device)
10437 {
10438     const struct tvertex quad1[] =
10439     {
10440         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10441         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10442         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10443         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10444     };
10445     const struct tvertex quad2[] =
10446     {
10447         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10448         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10449         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10450         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10451     };
10452     const struct vertex quad3[] =
10453     {
10454         {-0.65, 0.55,  5.0f,      0xffffffff},
10455         {-0.35, 0.55,  5.0f,      0xffffffff},
10456         {-0.65, 0.15,  5.0f,      0xffffffff},
10457         {-0.35, 0.15,  5.0f,      0xffffffff},
10458     };
10459     const struct vertex quad4[] =
10460     {
10461         {-0.87, 0.83, 10.0f,      0xffffffff},
10462         {-0.65, 0.83, 10.0f,      0xffffffff},
10463         {-0.87, 0.55, 10.0f,      0xffffffff},
10464         {-0.65, 0.55, 10.0f,      0xffffffff},
10465     };
10466     const struct vertex quad5[] =
10467     {
10468         { -0.5,  0.5, 10.0f,      0xff14f914},
10469         {  0.5,  0.5, 10.0f,      0xff14f914},
10470         { -0.5, -0.5, 10.0f,      0xff14f914},
10471         {  0.5, -0.5, 10.0f,      0xff14f914},
10472     };
10473     const struct tvertex quad6[] =
10474     {
10475         {    0,  120, 10.0f, 1.0, 0xfff91414},
10476         {  640,  120, 10.0f, 1.0, 0xfff91414},
10477         {    0,  180, 10.0f, 1.0, 0xfff91414},
10478         {  640,  180, 10.0f, 1.0, 0xfff91414},
10479     };
10480
10481     D3DVIEWPORT9 vp;
10482     D3DCOLOR color;
10483     HRESULT hr;
10484
10485     vp.X = 0;
10486     vp.Y = 0;
10487     vp.Width = 640;
10488     vp.Height = 480;
10489     vp.MinZ = 0.0;
10490     vp.MaxZ = 7.5;
10491
10492     hr = IDirect3DDevice9_SetViewport(device, &vp);
10493     if(FAILED(hr))
10494     {
10495         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10496          * the tests because the 7.5 is just intended to show that it doesn't have
10497          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10498          * viewport and continue.
10499          */
10500         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10501         vp.MaxZ = 1.0;
10502         hr = IDirect3DDevice9_SetViewport(device, &vp);
10503     }
10504     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10505
10506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10507     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10508
10509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10510     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10511     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10512     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10513     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10514     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10515     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10516     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10517
10518     hr = IDirect3DDevice9_BeginScene(device);
10519     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10520
10521     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10522     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10523
10524     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10525     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10526     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10527     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10528
10529     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10530     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10531
10532     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10533     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10534     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10535     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10536
10537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10538     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10539
10540     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10541     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10542
10543     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10544     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10545
10546     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10547     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10548
10549     hr = IDirect3DDevice9_EndScene(device);
10550     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10551
10552     color = getPixelColor(device, 75, 75);
10553     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10554     color = getPixelColor(device, 150, 150);
10555     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10556     color = getPixelColor(device, 320, 240);
10557     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10558     color = getPixelColor(device, 320, 330);
10559     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10560     color = getPixelColor(device, 320, 330);
10561     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10562
10563     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10564     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10565
10566     vp.MinZ = 0.0;
10567     vp.MaxZ = 1.0;
10568     hr = IDirect3DDevice9_SetViewport(device, &vp);
10569     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10570 }
10571
10572 static void depth_bounds_test(IDirect3DDevice9 *device)
10573 {
10574     const struct tvertex quad1[] =
10575     {
10576         {    0,    0, 0.0f, 1, 0xfff9e814},
10577         {  640,    0, 0.0f, 1, 0xfff9e814},
10578         {    0,  480, 1.0f, 1, 0xfff9e814},
10579         {  640,  480, 1.0f, 1, 0xfff9e814},
10580     };
10581     const struct tvertex quad2[] =
10582     {
10583         {    0,    0,  0.6f, 1, 0xff002b7f},
10584         {  640,    0,  0.6f, 1, 0xff002b7f},
10585         {    0,  480,  0.6f, 1, 0xff002b7f},
10586         {  640,  480,  0.6f, 1, 0xff002b7f},
10587     };
10588     const struct tvertex quad3[] =
10589     {
10590         {    0,  100, 0.6f, 1, 0xfff91414},
10591         {  640,  100, 0.6f, 1, 0xfff91414},
10592         {    0,  160, 0.6f, 1, 0xfff91414},
10593         {  640,  160, 0.6f, 1, 0xfff91414},
10594     };
10595
10596     union {
10597         DWORD d;
10598         float f;
10599     } tmpvalue;
10600
10601     IDirect3D9 *d3d = NULL;
10602     IDirect3DSurface9 *offscreen_surface = NULL;
10603     D3DCOLOR color;
10604     HRESULT hr;
10605
10606     IDirect3DDevice9_GetDirect3D(device, &d3d);
10607     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10608             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10609         skip("No NVDB (depth bounds test) support\n");
10610         IDirect3D9_Release(d3d);
10611         return;
10612     }
10613     IDirect3D9_Release(d3d);
10614
10615     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10616             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10617     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10618     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10619
10620     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10621     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10622
10623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10624     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10626     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10627     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10628     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10629     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10630     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10631
10632
10633     hr = IDirect3DDevice9_BeginScene(device);
10634     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10635
10636     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10637     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10638
10639     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10640     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10641
10642     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10643     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10644
10645     tmpvalue.f = 0.625;
10646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10647     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10648
10649     tmpvalue.f = 0.75;
10650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10651     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10652
10653     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10654     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10655
10656     tmpvalue.f = 0.75;
10657     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10658     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10659
10660     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10661     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10662
10663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10664     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10665
10666     hr = IDirect3DDevice9_EndScene(device);
10667     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10668
10669     color = getPixelColor(device, 150, 130);
10670     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10671     color = getPixelColor(device, 150, 200);
10672     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10673     color = getPixelColor(device, 150, 300-5);
10674     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10675     color = getPixelColor(device, 150, 300+5);
10676     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10677     color = getPixelColor(device, 150, 330);
10678     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10679     color = getPixelColor(device, 150, 360-5);
10680     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10681     color = getPixelColor(device, 150, 360+5);
10682     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10683
10684     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10685     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10686 }
10687
10688 static void depth_buffer_test(IDirect3DDevice9 *device)
10689 {
10690     static const struct vertex quad1[] =
10691     {
10692         { -1.0,  1.0, 0.33f, 0xff00ff00},
10693         {  1.0,  1.0, 0.33f, 0xff00ff00},
10694         { -1.0, -1.0, 0.33f, 0xff00ff00},
10695         {  1.0, -1.0, 0.33f, 0xff00ff00},
10696     };
10697     static const struct vertex quad2[] =
10698     {
10699         { -1.0,  1.0, 0.50f, 0xffff00ff},
10700         {  1.0,  1.0, 0.50f, 0xffff00ff},
10701         { -1.0, -1.0, 0.50f, 0xffff00ff},
10702         {  1.0, -1.0, 0.50f, 0xffff00ff},
10703     };
10704     static const struct vertex quad3[] =
10705     {
10706         { -1.0,  1.0, 0.66f, 0xffff0000},
10707         {  1.0,  1.0, 0.66f, 0xffff0000},
10708         { -1.0, -1.0, 0.66f, 0xffff0000},
10709         {  1.0, -1.0, 0.66f, 0xffff0000},
10710     };
10711     static const DWORD expected_colors[4][4] =
10712     {
10713         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10714         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10715         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10716         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10717     };
10718
10719     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10720     unsigned int i, j;
10721     D3DVIEWPORT9 vp;
10722     D3DCOLOR color;
10723     HRESULT hr;
10724
10725     vp.X = 0;
10726     vp.Y = 0;
10727     vp.Width = 640;
10728     vp.Height = 480;
10729     vp.MinZ = 0.0;
10730     vp.MaxZ = 1.0;
10731
10732     hr = IDirect3DDevice9_SetViewport(device, &vp);
10733     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10734
10735     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10736     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10737     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10738     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10739     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10740     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10741     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10742     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10743     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10744     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10745
10746     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10747     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10748     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10749             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10750     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10751     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10752             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10753     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10754     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10755             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10756     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10757
10758     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10759     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10760     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10761     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10762
10763     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10764     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10766     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10767
10768     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10769     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10770     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10771     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10772
10773     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10774     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10775     hr = IDirect3DDevice9_BeginScene(device);
10776     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10777     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10778     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10779     hr = IDirect3DDevice9_EndScene(device);
10780     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10781
10782     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10783     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10784     IDirect3DSurface9_Release(backbuffer);
10785     IDirect3DSurface9_Release(rt3);
10786     IDirect3DSurface9_Release(rt2);
10787     IDirect3DSurface9_Release(rt1);
10788
10789     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10790     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10791
10792     hr = IDirect3DDevice9_BeginScene(device);
10793     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10794     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10795     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10796     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10797     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10798     hr = IDirect3DDevice9_EndScene(device);
10799     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10800
10801     for (i = 0; i < 4; ++i)
10802     {
10803         for (j = 0; j < 4; ++j)
10804         {
10805             unsigned int x = 80 * ((2 * j) + 1);
10806             unsigned int y = 60 * ((2 * i) + 1);
10807             color = getPixelColor(device, x, y);
10808             ok(color_match(color, expected_colors[i][j], 0),
10809                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10810         }
10811     }
10812
10813     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10814     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10815 }
10816
10817 static void intz_test(IDirect3DDevice9 *device)
10818 {
10819     static const DWORD ps_code[] =
10820     {
10821         0xffff0200,                                                             /* ps_2_0                       */
10822         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
10823         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
10824         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
10825         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
10826         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
10827         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
10828         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
10829         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
10830         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
10831         0x0000ffff,                                                             /* end                          */
10832     };
10833     struct
10834     {
10835         float x, y, z;
10836         float s, t, p, q;
10837     }
10838     quad[] =
10839     {
10840         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
10841         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
10842         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
10843         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
10844     };
10845     struct
10846     {
10847         UINT x, y;
10848         D3DCOLOR color;
10849     }
10850     expected_colors[] =
10851     {
10852         {400,  60, D3DCOLOR_ARGB(0x00, 0x9f, 0xff, 0x00)},
10853         {560, 180, D3DCOLOR_ARGB(0x00, 0xdf, 0x55, 0x00)},
10854         {560, 300, D3DCOLOR_ARGB(0x00, 0xdf, 0x66, 0x00)},
10855         {400, 420, D3DCOLOR_ARGB(0x00, 0x9f, 0xb6, 0x00)},
10856         {240, 420, D3DCOLOR_ARGB(0x00, 0x60, 0x6d, 0x00)},
10857         { 80, 300, D3DCOLOR_ARGB(0x00, 0x20, 0x33, 0x00)},
10858         { 80, 180, D3DCOLOR_ARGB(0x00, 0x20, 0x55, 0x00)},
10859         {240,  60, D3DCOLOR_ARGB(0x00, 0x60, 0xff, 0x00)},
10860     };
10861
10862     IDirect3DSurface9 *original_ds, *original_rt, *rt;
10863     IDirect3DTexture9 *texture;
10864     IDirect3DPixelShader9 *ps;
10865     IDirect3DSurface9 *ds;
10866     IDirect3D9 *d3d9;
10867     D3DCAPS9 caps;
10868     HRESULT hr;
10869     UINT i;
10870
10871     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10872     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
10873     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
10874     {
10875         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
10876         return;
10877     }
10878
10879     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
10880     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
10881
10882     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10883             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
10884     if (FAILED(hr))
10885     {
10886         skip("No INTZ support, skipping INTZ test.\n");
10887         return;
10888     }
10889
10890     IDirect3D9_Release(d3d9);
10891
10892     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
10893     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10894     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
10895     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
10896
10897     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
10898             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
10899     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
10900     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
10901             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
10902     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10903     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
10904     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
10905
10906     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
10907     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10908     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10909     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10910     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10911     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10912     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10913     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10914     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10915     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10916
10917     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10918     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10919     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10920     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10921     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10922     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10923     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10924     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10925     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
10926     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10927
10928     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
10929     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
10930     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
10931     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10932     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10933     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10934     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10935     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10936
10937     /* Setup the depth/stencil surface. */
10938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
10939     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10940
10941     hr = IDirect3DDevice9_BeginScene(device);
10942     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10943     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10944     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10945     hr = IDirect3DDevice9_EndScene(device);
10946     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10947
10948     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
10949     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10950     IDirect3DSurface9_Release(ds);
10951     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
10952     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10953     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10954     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10955     hr = IDirect3DDevice9_SetPixelShader(device, ps);
10956     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10957
10958     /* Read the depth values back. */
10959     hr = IDirect3DDevice9_BeginScene(device);
10960     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10961     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10962     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10963     hr = IDirect3DDevice9_EndScene(device);
10964     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10965
10966     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
10967     {
10968         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
10969         ok(color_match(color, expected_colors[i].color, 1),
10970                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
10971                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
10972     }
10973
10974     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10975     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
10976
10977     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
10978     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10979     IDirect3DSurface9_Release(original_ds);
10980     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10981     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10982     IDirect3DTexture9_Release(texture);
10983     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10984     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10985     IDirect3DPixelShader9_Release(ps);
10986
10987     IDirect3DSurface9_Release(original_rt);
10988     IDirect3DSurface9_Release(rt);
10989 }
10990
10991 static void shadow_test(IDirect3DDevice9 *device)
10992 {
10993     static const DWORD ps_code[] =
10994     {
10995         0xffff0200,                                                             /* ps_2_0                       */
10996         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
10997         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
10998         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
10999         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11000         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11001         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11002         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11003         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11004         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11005         0x0000ffff,                                                             /* end                          */
11006     };
11007     struct
11008     {
11009         D3DFORMAT format;
11010         const char *name;
11011     }
11012     formats[] =
11013     {
11014         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11015         {D3DFMT_D32,            "D3DFMT_D32"},
11016         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11017         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11018         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11019         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11020         {D3DFMT_D16,            "D3DFMT_D16"},
11021         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11022         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11023     };
11024     struct
11025     {
11026         float x, y, z;
11027         float s, t, p, q;
11028     }
11029     quad[] =
11030     {
11031         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11032         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11033         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11034         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11035     };
11036     struct
11037     {
11038         UINT x, y;
11039         D3DCOLOR color;
11040     }
11041     expected_colors[] =
11042     {
11043         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11044         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11045         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11046         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11047         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11048         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11049         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11050         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11051     };
11052
11053     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11054     IDirect3DPixelShader9 *ps;
11055     IDirect3D9 *d3d9;
11056     D3DCAPS9 caps;
11057     HRESULT hr;
11058     UINT i;
11059
11060     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11061     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11062     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11063     {
11064         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11065         return;
11066     }
11067
11068     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11069     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11070     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11071     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11072     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11073     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11074
11075     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11076             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11077     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11078     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11079     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11080
11081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11082     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11083     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11084     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11085     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11086     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11087     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11088     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11089     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11090     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11091
11092     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11093     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11094     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11095     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11096     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11097     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11098     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11099     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11100     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11101     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11102
11103     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11104     {
11105         D3DFORMAT format = formats[i].format;
11106         IDirect3DTexture9 *texture;
11107         IDirect3DSurface9 *ds;
11108         unsigned int j;
11109
11110         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11111                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11112         if (FAILED(hr)) continue;
11113
11114         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11115                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11116         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11117
11118         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11119         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11120
11121         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11122         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11123
11124         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11125         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11126
11127         IDirect3DDevice9_SetPixelShader(device, NULL);
11128         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11129
11130         /* Setup the depth/stencil surface. */
11131         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11132         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11133
11134         hr = IDirect3DDevice9_BeginScene(device);
11135         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11137         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11138         hr = IDirect3DDevice9_EndScene(device);
11139         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11140
11141         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11142         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11143         IDirect3DSurface9_Release(ds);
11144
11145         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11146         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11147
11148         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11149         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11150
11151         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11152         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11153
11154         /* Do the actual shadow mapping. */
11155         hr = IDirect3DDevice9_BeginScene(device);
11156         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11157         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11158         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11159         hr = IDirect3DDevice9_EndScene(device);
11160         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11161
11162         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11163         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11164         IDirect3DTexture9_Release(texture);
11165
11166         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11167         {
11168             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11169             ok(color_match(color, expected_colors[j].color, 0),
11170                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11171                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11172                     formats[i].name, color);
11173         }
11174
11175         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11176         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11177     }
11178
11179     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11180     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11181     IDirect3DPixelShader9_Release(ps);
11182
11183     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11184     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11185     IDirect3DSurface9_Release(original_ds);
11186
11187     IDirect3DSurface9_Release(original_rt);
11188     IDirect3DSurface9_Release(rt);
11189
11190     IDirect3D9_Release(d3d9);
11191 }
11192
11193 static void fp_special_test(IDirect3DDevice9 *device)
11194 {
11195     static const DWORD vs_header[] =
11196     {
11197         0xfffe0200,                                                             /* vs_2_0                       */
11198         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11199         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
11200         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
11201     };
11202
11203     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
11204     static const DWORD vs_pow[] =
11205             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
11206     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
11207     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
11208     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
11209     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
11210     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
11211
11212     static const DWORD vs_footer[] =
11213     {
11214         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
11215         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
11216         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
11217         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
11218         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11219         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
11220         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
11221         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
11222         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11223         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
11224         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
11225         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
11226         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
11227         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
11228         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
11229         0x0000ffff,                                                             /* end                          */
11230     };
11231
11232     static const struct
11233     {
11234         const char *name;
11235         const DWORD *ops;
11236         DWORD size;
11237         D3DCOLOR color1;
11238         D3DCOLOR color2;
11239     }
11240     vs_body[] =
11241     {
11242         /* The basic ideas here are:
11243          *     2.0 * +/-INF == +/-INF
11244          *     NAN != NAN
11245          *
11246          * The vertex shader value is written to the red component, with 0.0
11247          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11248          * result in 0x00. The pixel shader value is written to the green
11249          * component, but here 0.0 also results in 0x00. The actual value is
11250          * written to the blue component.
11251          *
11252          * There are at least two different ways for D3D implementations to
11253          * handle this. AMD seems to stick mostly to the D3D documentation,
11254          * and doesn't generate floating point specials in the first place.
11255          * Note that that doesn't just apply to functions like rcp and rsq,
11256          * but also basic mul, add, etc. nVidia seems to generate infinities,
11257          * but then clamp them before sending them to the interpolators. In
11258          * OpenGL these aren't clamped, and interpolating them generates NANs
11259          * in the fragment shader, unless flat shading is used (essentially
11260          * replicating the values instead of interpolating them).
11261          *
11262          * I can't currently explain the nVidia results for pow and nrm.
11263          * They're not specials in the vertex shader, but look like -INF in
11264          * the pixel shader. */
11265         {"log",     vs_log,     sizeof(vs_log),     0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
11266         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff /* +FLT_MAX */,  0x0000ff00 /* ???         */},
11267         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000 /*  0.0     */,  0x0000ff00 /* ???         */},
11268         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
11269         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
11270         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
11271         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
11272     };
11273
11274     static const DWORD ps_code[] =
11275     {
11276         0xffff0200,                                                             /* ps_2_0                       */
11277         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11278         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
11279         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
11280         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
11281         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
11282         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
11283         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
11284         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
11285         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
11286         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
11287         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
11288         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
11289         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
11290         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
11291         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
11292         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
11293         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
11294         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
11295         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
11296         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
11297         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
11298         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
11299         0x0000ffff,                                                             /* end                          */
11300     };
11301
11302     struct
11303     {
11304         float x, y, z;
11305         float s;
11306     }
11307     quad[] =
11308     {
11309         { -1.0f,  1.0f, 0.0f, 0.0f},
11310         {  1.0f,  1.0f, 1.0f, 0.0f},
11311         { -1.0f, -1.0f, 0.0f, 0.0f},
11312         {  1.0f, -1.0f, 1.0f, 0.0f},
11313     };
11314
11315     IDirect3DPixelShader9 *ps;
11316     UINT body_size = 0;
11317     DWORD *vs_code;
11318     D3DCAPS9 caps;
11319     HRESULT hr;
11320     UINT i;
11321
11322     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11323     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11324     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11325     {
11326         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11327         return;
11328     }
11329
11330     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11331     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11332
11333     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11334     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11335     IDirect3DDevice9_SetPixelShader(device, ps);
11336     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11337
11338     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11339     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11340
11341     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11342     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11343
11344     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11345     {
11346         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11347     }
11348
11349     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11350     memcpy(vs_code, vs_header, sizeof(vs_header));
11351
11352     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11353     {
11354         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11355         IDirect3DVertexShader9 *vs;
11356         D3DCOLOR color;
11357
11358         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11359         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11360         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11361
11362         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11363         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11364         IDirect3DDevice9_SetVertexShader(device, vs);
11365         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11366
11367         hr = IDirect3DDevice9_BeginScene(device);
11368         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11369         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11370         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11371         hr = IDirect3DDevice9_EndScene(device);
11372         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11373
11374         color = getPixelColor(device, 320, 240);
11375         ok(color_match(color, vs_body[i].color1, 1) || color_match(color, vs_body[i].color2, 1),
11376                 "Expected color 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11377                 vs_body[i].color1, vs_body[i].color2, vs_body[i].name, color);
11378
11379         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11380         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11381
11382         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11383         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11384         IDirect3DVertexShader9_Release(vs);
11385     }
11386
11387     HeapFree(GetProcessHeap(), 0, vs_code);
11388
11389     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11390     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11391     IDirect3DPixelShader9_Release(ps);
11392 }
11393
11394 START_TEST(visual)
11395 {
11396     IDirect3DDevice9 *device_ptr;
11397     D3DCAPS9 caps;
11398     HRESULT hr;
11399     DWORD color;
11400
11401     d3d9_handle = LoadLibraryA("d3d9.dll");
11402     if (!d3d9_handle)
11403     {
11404         skip("Could not load d3d9.dll\n");
11405         return;
11406     }
11407
11408     device_ptr = init_d3d9();
11409     if (!device_ptr)
11410     {
11411         skip("Creating the device failed\n");
11412         return;
11413     }
11414
11415     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11416
11417     /* Check for the reliability of the returned data */
11418     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11419     if(FAILED(hr))
11420     {
11421         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11422         goto cleanup;
11423     }
11424
11425     color = getPixelColor(device_ptr, 1, 1);
11426     if(color !=0x00ff0000)
11427     {
11428         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11429         goto cleanup;
11430     }
11431     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11432
11433     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11434     if(FAILED(hr))
11435     {
11436         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11437         goto cleanup;
11438     }
11439
11440     color = getPixelColor(device_ptr, 639, 479);
11441     if(color != 0x0000ddee)
11442     {
11443         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11444         goto cleanup;
11445     }
11446     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11447
11448     /* Now execute the real tests */
11449     depth_clamp_test(device_ptr);
11450     stretchrect_test(device_ptr);
11451     lighting_test(device_ptr);
11452     clear_test(device_ptr);
11453     color_fill_test(device_ptr);
11454     fog_test(device_ptr);
11455     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11456     {
11457         test_cube_wrap(device_ptr);
11458     } else {
11459         skip("No cube texture support\n");
11460     }
11461     z_range_test(device_ptr);
11462     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11463     {
11464         maxmip_test(device_ptr);
11465     }
11466     else
11467     {
11468         skip("No mipmap support\n");
11469     }
11470     offscreen_test(device_ptr);
11471     alpha_test(device_ptr);
11472     shademode_test(device_ptr);
11473     srgbtexture_test(device_ptr);
11474     release_buffer_test(device_ptr);
11475     float_texture_test(device_ptr);
11476     g16r16_texture_test(device_ptr);
11477     pixelshader_blending_test(device_ptr);
11478     texture_transform_flags_test(device_ptr);
11479     autogen_mipmap_test(device_ptr);
11480     fixed_function_decl_test(device_ptr);
11481     conditional_np2_repeat_test(device_ptr);
11482     fixed_function_bumpmap_test(device_ptr);
11483     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11484         stencil_cull_test(device_ptr);
11485     } else {
11486         skip("No two sided stencil support\n");
11487     }
11488     pointsize_test(device_ptr);
11489     tssargtemp_test(device_ptr);
11490     np2_stretch_rect_test(device_ptr);
11491     yuv_color_test(device_ptr);
11492     zwriteenable_test(device_ptr);
11493     alphatest_test(device_ptr);
11494     viewport_test(device_ptr);
11495
11496     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11497     {
11498         test_constant_clamp_vs(device_ptr);
11499         test_compare_instructions(device_ptr);
11500     }
11501     else skip("No vs_1_1 support\n");
11502
11503     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11504     {
11505         test_mova(device_ptr);
11506         loop_index_test(device_ptr);
11507         sincos_test(device_ptr);
11508         sgn_test(device_ptr);
11509         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11510             test_vshader_input(device_ptr);
11511             test_vshader_float16(device_ptr);
11512             stream_test(device_ptr);
11513         } else {
11514             skip("No vs_3_0 support\n");
11515         }
11516     }
11517     else skip("No vs_2_0 support\n");
11518
11519     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11520     {
11521         fog_with_shader_test(device_ptr);
11522     }
11523     else skip("No vs_1_1 and ps_1_1 support\n");
11524
11525     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11526     {
11527         texbem_test(device_ptr);
11528         texdepth_test(device_ptr);
11529         texkill_test(device_ptr);
11530         x8l8v8u8_test(device_ptr);
11531         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11532             constant_clamp_ps_test(device_ptr);
11533             cnd_test(device_ptr);
11534             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11535                 dp2add_ps_test(device_ptr);
11536                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11537                     nested_loop_test(device_ptr);
11538                     fixed_function_varying_test(device_ptr);
11539                     vFace_register_test(device_ptr);
11540                     vpos_register_test(device_ptr);
11541                     multiple_rendertargets_test(device_ptr);
11542                 } else {
11543                     skip("No ps_3_0 or vs_3_0 support\n");
11544                 }
11545             } else {
11546                 skip("No ps_2_0 support\n");
11547             }
11548         }
11549     }
11550     else skip("No ps_1_1 support\n");
11551
11552     texop_test(device_ptr);
11553     texop_range_test(device_ptr);
11554     alphareplicate_test(device_ptr);
11555     dp3_alpha_test(device_ptr);
11556     depth_buffer_test(device_ptr);
11557     intz_test(device_ptr);
11558     shadow_test(device_ptr);
11559     fp_special_test(device_ptr);
11560     depth_bounds_test(device_ptr);
11561
11562 cleanup:
11563     if(device_ptr) {
11564         D3DPRESENT_PARAMETERS present_parameters;
11565         IDirect3DSwapChain9 *swapchain;
11566         ULONG ref;
11567
11568         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11569         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11570         IDirect3DSwapChain9_Release(swapchain);
11571         ref = IDirect3DDevice9_Release(device_ptr);
11572         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11573         DestroyWindow(present_parameters.hDeviceWindow);
11574     }
11575 }