ddraw: Get rid of ddcomimpl.h.
[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_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47     return ret;
48 }
49
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
51 {
52     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53     c1 >>= 8; c2 >>= 8;
54     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55     c1 >>= 8; c2 >>= 8;
56     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57     c1 >>= 8; c2 >>= 8;
58     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59     return TRUE;
60 }
61
62 /* Locks a given surface and returns the color at (x,y).  It's the caller's
63  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
65 {
66     DWORD color;
67     HRESULT hr;
68     D3DSURFACE_DESC desc;
69     RECT rectToLock = {x, y, x+1, y+1};
70     D3DLOCKED_RECT lockedRect;
71
72     hr = IDirect3DSurface9_GetDesc(surface, &desc);
73     if(FAILED(hr))  /* This is not a test */
74     {
75         trace("Can't get the surface description, hr=%08x\n", hr);
76         return 0xdeadbeef;
77     }
78
79     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80     if(FAILED(hr))  /* This is not a test */
81     {
82         trace("Can't lock the surface, hr=%08x\n", hr);
83         return 0xdeadbeef;
84     }
85     switch(desc.Format) {
86         case D3DFMT_A8R8G8B8:
87         {
88             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89             break;
90         }
91         default:
92             trace("Error: unknown surface format: %d\n", desc.Format);
93             color = 0xdeadbeef;
94             break;
95     }
96     hr = IDirect3DSurface9_UnlockRect(surface);
97     if(FAILED(hr))
98     {
99         trace("Can't unlock the surface, hr=%08x\n", hr);
100     }
101     return color;
102 }
103
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
105 {
106     DWORD ret;
107     IDirect3DSurface9 *surf;
108     HRESULT hr;
109     D3DLOCKED_RECT lockedRect;
110     RECT rectToLock = {x, y, x+1, y+1};
111
112     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113     if(FAILED(hr) || !surf )  /* This is not a test */
114     {
115         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116         return 0xdeadbeef;
117     }
118
119     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120     if(FAILED(hr))
121     {
122         trace("Can't read the front buffer data, hr=%08x\n", hr);
123         ret = 0xdeadbeed;
124         goto out;
125     }
126
127     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128     if(FAILED(hr))
129     {
130         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131         ret = 0xdeadbeec;
132         goto out;
133     }
134
135     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136      * really important for these tests
137      */
138     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139     hr = IDirect3DSurface9_UnlockRect(surf);
140     if(FAILED(hr))
141     {
142         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
143     }
144
145 out:
146     if(surf) IDirect3DSurface9_Release(surf);
147     return ret;
148 }
149
150 static IDirect3DDevice9 *init_d3d9(void)
151 {
152     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153     IDirect3D9 *d3d9_ptr = 0;
154     IDirect3DDevice9 *device_ptr = 0;
155     D3DPRESENT_PARAMETERS present_parameters;
156     HRESULT hr;
157     D3DADAPTER_IDENTIFIER9 identifier;
158
159     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161     if (!d3d9_create) return NULL;
162
163     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164     if (!d3d9_ptr)
165     {
166         skip("could not create D3D9\n");
167         return NULL;
168     }
169
170     ZeroMemory(&present_parameters, sizeof(present_parameters));
171     present_parameters.Windowed = FALSE;
172     present_parameters.hDeviceWindow = create_window();
173     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
174     present_parameters.BackBufferWidth = 640;
175     present_parameters.BackBufferHeight = 480;
176     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
177     present_parameters.EnableAutoDepthStencil = TRUE;
178     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
179
180     memset(&identifier, 0, sizeof(identifier));
181     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
182     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
183     trace("Driver string: \"%s\"\n", identifier.Driver);
184     trace("Description string: \"%s\"\n", identifier.Description);
185     trace("Device name string: \"%s\"\n", identifier.DeviceName);
186     trace("Driver version %d.%d.%d.%d\n",
187           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
188           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
189
190     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191     if(FAILED(hr)) {
192         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
193         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
194         if(FAILED(hr)) {
195             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196         }
197     }
198     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
199
200     return device_ptr;
201 }
202
203 struct vertex
204 {
205     float x, y, z;
206     DWORD diffuse;
207 };
208
209 struct tvertex
210 {
211     float x, y, z, rhw;
212     DWORD diffuse;
213 };
214
215 struct nvertex
216 {
217     float x, y, z;
218     float nx, ny, nz;
219     DWORD diffuse;
220 };
221
222 static void lighting_test(IDirect3DDevice9 *device)
223 {
224     HRESULT hr;
225     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
226     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
227     DWORD color;
228     D3DMATERIAL9 material, old_material;
229     DWORD cop, carg;
230
231     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
232                       0.0f, 1.0f, 0.0f, 0.0f,
233                       0.0f, 0.0f, 1.0f, 0.0f,
234                       0.0f, 0.0f, 0.0f, 1.0f };
235
236     struct vertex unlitquad[] =
237     {
238         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
239         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
240         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
241         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
242     };
243     struct vertex litquad[] =
244     {
245         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
246         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
247         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
248         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
249     };
250     struct nvertex unlitnquad[] =
251     {
252         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
253         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
254         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
255         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
256     };
257     struct nvertex litnquad[] =
258     {
259         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
260         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
261         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
262         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
263     };
264     WORD Indices[] = {0, 1, 2, 2, 3, 0};
265
266     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
267     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
268
269     /* Setup some states that may cause issues */
270     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
272     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
275     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
277     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
278     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
279     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
281     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
294
295     hr = IDirect3DDevice9_SetFVF(device, fvf);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
297
298     hr = IDirect3DDevice9_BeginScene(device);
299     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
300     if(hr == D3D_OK)
301     {
302         /* No lights are defined... That means, lit vertices should be entirely black */
303         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
304         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
305         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
306                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
307         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
308
309         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
310         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
311         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
312                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
313         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
314
315         hr = IDirect3DDevice9_SetFVF(device, nfvf);
316         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
317
318         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323
324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
328         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329
330         IDirect3DDevice9_EndScene(device);
331         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
332     }
333
334     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
335
336     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
337     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
338     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
339     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
340     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
341     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
342     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
343     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
344
345     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
346     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
347     memset(&material, 0, sizeof(material));
348     material.Diffuse.r = 0.0;
349     material.Diffuse.g = 0.0;
350     material.Diffuse.b = 0.0;
351     material.Diffuse.a = 1.0;
352     material.Ambient.r = 0.0;
353     material.Ambient.g = 0.0;
354     material.Ambient.b = 0.0;
355     material.Ambient.a = 0.0;
356     material.Specular.r = 0.0;
357     material.Specular.g = 0.0;
358     material.Specular.b = 0.0;
359     material.Specular.a = 0.0;
360     material.Emissive.r = 0.0;
361     material.Emissive.g = 0.0;
362     material.Emissive.b = 0.0;
363     material.Emissive.a = 0.0;
364     material.Power = 0.0;
365     IDirect3DDevice9_SetMaterial(device, &material);
366     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
367
368     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
369     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
370     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
371     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
372
373     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
374     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
375     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
376     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
377     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
378     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
379     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
380     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
381
382     hr = IDirect3DDevice9_BeginScene(device);
383     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
384     if(SUCCEEDED(hr)) {
385         struct vertex lighting_test[] = {
386             {-1.0,   -1.0,   0.1,    0x8000ff00},
387             { 1.0,   -1.0,   0.1,    0x80000000},
388             {-1.0,    1.0,   0.1,    0x8000ff00},
389             { 1.0,    1.0,   0.1,    0x80000000}
390         };
391         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
392         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
393         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
394         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
395
396         hr = IDirect3DDevice9_EndScene(device);
397         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
398     }
399
400     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
401     color = getPixelColor(device, 320, 240);
402     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
403
404     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
405     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
406     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
407     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
408     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
409     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
410     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
411     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
412     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
413     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
414     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
415     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
416 }
417
418 static void clear_test(IDirect3DDevice9 *device)
419 {
420     /* Tests the correctness of clearing parameters */
421     HRESULT hr;
422     D3DRECT rect[2];
423     D3DRECT rect_negneg;
424     DWORD color;
425     D3DVIEWPORT9 old_vp, vp;
426     RECT scissor;
427     DWORD oldColorWrite;
428     BOOL invalid_clear_failed = FALSE;
429
430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
432
433     /* Positive x, negative y */
434     rect[0].x1 = 0;
435     rect[0].y1 = 480;
436     rect[0].x2 = 320;
437     rect[0].y2 = 240;
438
439     /* Positive x, positive y */
440     rect[1].x1 = 0;
441     rect[1].y1 = 0;
442     rect[1].x2 = 320;
443     rect[1].y2 = 240;
444     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
445      * returns D3D_OK, but ignores the rectangle silently
446      */
447     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
448     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
449     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
450
451     /* negative x, negative y */
452     rect_negneg.x1 = 640;
453     rect_negneg.y1 = 240;
454     rect_negneg.x2 = 320;
455     rect_negneg.y2 = 0;
456     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
457     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
458     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
459
460     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
461
462     color = getPixelColor(device, 160, 360); /* lower left quad */
463     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
464     color = getPixelColor(device, 160, 120); /* upper left quad */
465     if(invalid_clear_failed) {
466         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
467         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
468     } else {
469         /* If the negative rectangle was dropped silently, the correct ones are cleared */
470         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
471     }
472     color = getPixelColor(device, 480, 360); /* lower right quad  */
473     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
474     color = getPixelColor(device, 480, 120); /* upper right quad */
475     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
476
477     /* Test how the viewport affects clears */
478     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
479     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
480     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
481     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
482
483     vp.X = 160;
484     vp.Y = 120;
485     vp.Width = 160;
486     vp.Height = 120;
487     vp.MinZ = 0.0;
488     vp.MaxZ = 1.0;
489     hr = IDirect3DDevice9_SetViewport(device, &vp);
490     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
491     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
492     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
493
494     vp.X = 320;
495     vp.Y = 240;
496     vp.Width = 320;
497     vp.Height = 240;
498     vp.MinZ = 0.0;
499     vp.MaxZ = 1.0;
500     hr = IDirect3DDevice9_SetViewport(device, &vp);
501     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
502     rect[0].x1 = 160;
503     rect[0].y1 = 120;
504     rect[0].x2 = 480;
505     rect[0].y2 = 360;
506     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
508
509     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
510     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
511
512     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
513     color = getPixelColor(device, 158, 118);
514     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
515     color = getPixelColor(device, 162, 118);
516     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
517     color = getPixelColor(device, 158, 122);
518     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
519     color = getPixelColor(device, 162, 122);
520     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
521
522     color = getPixelColor(device, 318, 238);
523     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
524     color = getPixelColor(device, 322, 238);
525     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
526     color = getPixelColor(device, 318, 242);
527     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
528     color = getPixelColor(device, 322, 242);
529     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
530
531     color = getPixelColor(device, 478, 358);
532     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
533     color = getPixelColor(device, 482, 358);
534     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
535     color = getPixelColor(device, 478, 362);
536     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
537     color = getPixelColor(device, 482, 362);
538     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
539
540     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
541     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
542
543     scissor.left = 160;
544     scissor.right = 480;
545     scissor.top = 120;
546     scissor.bottom = 360;
547     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
548     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
550     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
551
552     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
553     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
554     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
555     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
556
557     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
558     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
559
560     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
561     color = getPixelColor(device, 158, 118);
562     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
563     color = getPixelColor(device, 162, 118);
564     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
565     color = getPixelColor(device, 158, 122);
566     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
567     color = getPixelColor(device, 162, 122);
568     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
569
570     color = getPixelColor(device, 158, 358);
571     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
572     color = getPixelColor(device, 162, 358);
573     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
574     color = getPixelColor(device, 158, 358);
575     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
576     color = getPixelColor(device, 162, 362);
577     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
578
579     color = getPixelColor(device, 478, 118);
580     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
581     color = getPixelColor(device, 478, 122);
582     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
583     color = getPixelColor(device, 482, 122);
584     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
585     color = getPixelColor(device, 482, 358);
586     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
587
588     color = getPixelColor(device, 478, 358);
589     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
590     color = getPixelColor(device, 478, 362);
591     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
592     color = getPixelColor(device, 482, 358);
593     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
594     color = getPixelColor(device, 482, 362);
595     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
596
597     color = getPixelColor(device, 318, 238);
598     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
599     color = getPixelColor(device, 318, 242);
600     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
601     color = getPixelColor(device, 322, 238);
602     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
603     color = getPixelColor(device, 322, 242);
604     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
605
606     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
607     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
608     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
609     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
610
611     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
612     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
613
614     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
615     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
616
617     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
618
619     /* Colorwriteenable does not affect the clear */
620     color = getPixelColor(device, 320, 240);
621     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
622 }
623
624 typedef struct {
625     float in[4];
626     DWORD out;
627 } test_data_t;
628
629 /*
630  *  c7      mova    ARGB            mov     ARGB
631  * -2.4     -2      0x00ffff00      -3      0x00ff0000
632  * -1.6     -2      0x00ffff00      -2      0x00ffff00
633  * -0.4      0      0x0000ffff      -1      0x0000ff00
634  *  0.4      0      0x0000ffff       0      0x0000ffff
635  *  1.6      2      0x00ff00ff       1      0x000000ff
636  *  2.4      2      0x00ff00ff       2      0x00ff00ff
637  */
638 static void test_mova(IDirect3DDevice9 *device)
639 {
640     static const DWORD mova_test[] = {
641         0xfffe0200,                                                             /* vs_2_0                       */
642         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
643         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
644         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
645         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
646         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
647         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
648         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
649         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
650         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
651         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
652         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
653         0x0000ffff                                                              /* END                          */
654     };
655     static const DWORD mov_test[] = {
656         0xfffe0101,                                                             /* vs_1_1                       */
657         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
658         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
659         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
660         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
661         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
662         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
663         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
664         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
665         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
666         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
667         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
668         0x0000ffff                                                              /* END                          */
669     };
670
671     static const test_data_t test_data[2][6] = {
672         {
673             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
674             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
675             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
676             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
677             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
678             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
679         },
680         {
681             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
682             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
683             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
684             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
685             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
686             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
687         }
688     };
689
690     static const float quad[][3] = {
691         {-1.0f, -1.0f, 0.0f},
692         {-1.0f,  1.0f, 0.0f},
693         { 1.0f, -1.0f, 0.0f},
694         { 1.0f,  1.0f, 0.0f},
695     };
696
697     static const D3DVERTEXELEMENT9 decl_elements[] = {
698         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
699         D3DDECL_END()
700     };
701
702     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
703     IDirect3DVertexShader9 *mova_shader = NULL;
704     IDirect3DVertexShader9 *mov_shader = NULL;
705     HRESULT hr;
706     UINT i, j;
707
708     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
709     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
710     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
711     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
712     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
713     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
714     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
715     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
716
717     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
718     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
719     for(j = 0; j < 2; ++j)
720     {
721         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
722         {
723             DWORD color;
724
725             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
726             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
727
728             hr = IDirect3DDevice9_BeginScene(device);
729             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
730
731             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
732             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
733
734             hr = IDirect3DDevice9_EndScene(device);
735             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
736
737             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
738             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
739
740             color = getPixelColor(device, 320, 240);
741             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
742                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
743
744             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
745             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
746         }
747         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
748         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
749     }
750
751     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
752     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
753
754     IDirect3DVertexDeclaration9_Release(vertex_declaration);
755     IDirect3DVertexShader9_Release(mova_shader);
756     IDirect3DVertexShader9_Release(mov_shader);
757 }
758
759 struct sVertex {
760     float x, y, z;
761     DWORD diffuse;
762     DWORD specular;
763 };
764
765 struct sVertexT {
766     float x, y, z, rhw;
767     DWORD diffuse;
768     DWORD specular;
769 };
770
771 static void fog_test(IDirect3DDevice9 *device)
772 {
773     HRESULT hr;
774     DWORD color;
775     BYTE r, g, b;
776     float start = 0.0f, end = 1.0f;
777     D3DCAPS9 caps;
778     int i;
779
780     /* Gets full z based fog with linear fog, no fog with specular color */
781     struct sVertex unstransformed_1[] = {
782         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
783         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
784         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
785         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
786     };
787     /* Ok, I am too lazy to deal with transform matrices */
788     struct sVertex unstransformed_2[] = {
789         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
790         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
791         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
792         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
793     };
794     /* Untransformed ones. Give them a different diffuse color to make the test look
795      * nicer. It also makes making sure that they are drawn correctly easier.
796      */
797     struct sVertexT transformed_1[] = {
798         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
799         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
800         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
801         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
802     };
803     struct sVertexT transformed_2[] = {
804         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
805         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
806         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
807         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
808     };
809     struct vertex rev_fog_quads[] = {
810        {-1.0,   -1.0,   0.1,    0x000000ff},
811        {-1.0,    0.0,   0.1,    0x000000ff},
812        { 0.0,    0.0,   0.1,    0x000000ff},
813        { 0.0,   -1.0,   0.1,    0x000000ff},
814
815        { 0.0,   -1.0,   0.9,    0x000000ff},
816        { 0.0,    0.0,   0.9,    0x000000ff},
817        { 1.0,    0.0,   0.9,    0x000000ff},
818        { 1.0,   -1.0,   0.9,    0x000000ff},
819
820        { 0.0,    0.0,   0.4,    0x000000ff},
821        { 0.0,    1.0,   0.4,    0x000000ff},
822        { 1.0,    1.0,   0.4,    0x000000ff},
823        { 1.0,    0.0,   0.4,    0x000000ff},
824
825        {-1.0,    0.0,   0.7,    0x000000ff},
826        {-1.0,    1.0,   0.7,    0x000000ff},
827        { 0.0,    1.0,   0.7,    0x000000ff},
828        { 0.0,    0.0,   0.7,    0x000000ff},
829     };
830     WORD Indices[] = {0, 1, 2, 2, 3, 0};
831
832     memset(&caps, 0, sizeof(caps));
833     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
834     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
835     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
836     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
837
838     /* Setup initial states: No lighting, fog on, fog color */
839     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
840     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
842     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
844     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
845
846     /* First test: Both table fog and vertex fog off */
847     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
848     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
849     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
850     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
851
852     /* Start = 0, end = 1. Should be default, but set them */
853     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
854     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
855     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
856     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
857
858     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
859     {
860         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
861         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
862         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
863         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
864                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
865                                                      sizeof(unstransformed_1[0]));
866         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
867
868         /* That makes it use the Z value */
869         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
870         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
871         /* Untransformed, vertex fog != none (or table fog != none):
872          * Use the Z value as input into the equation
873          */
874         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
875                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
876                                                      sizeof(unstransformed_1[0]));
877         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
878
879         /* transformed verts */
880         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
881         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
882         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
883         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
884                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
885                                                      sizeof(transformed_1[0]));
886         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
887
888         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
889         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
890         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
891          * equation
892          */
893         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
894                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
895                                                      sizeof(transformed_2[0]));
896
897         hr = IDirect3DDevice9_EndScene(device);
898         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
899     }
900     else
901     {
902         ok(FALSE, "BeginScene failed\n");
903     }
904
905     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
906     color = getPixelColor(device, 160, 360);
907     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
908     color = getPixelColor(device, 160, 120);
909     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
910     color = getPixelColor(device, 480, 120);
911     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
912     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
913     {
914         color = getPixelColor(device, 480, 360);
915         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
916     }
917     else
918     {
919         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
920          * The settings above result in no fogging with vertex fog
921          */
922         color = getPixelColor(device, 480, 120);
923         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
924         trace("Info: Table fog not supported by this device\n");
925     }
926
927     /* Now test the special case fogstart == fogend */
928     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
929     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
930
931     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
932     {
933         start = 512;
934         end = 512;
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         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
941         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
942         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
943         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
944         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
945         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
946
947         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
948          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
949          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
950          * The third transformed quad remains unfogged because the fogcoords are read from the specular
951          * color and has fixed fogstart and fogend.
952          */
953         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
954                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
955                 sizeof(unstransformed_1[0]));
956         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
957         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
959                 sizeof(unstransformed_1[0]));
960         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
961
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_EndScene(device);
971         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
972     }
973     else
974     {
975         ok(FALSE, "BeginScene failed\n");
976     }
977     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
978     color = getPixelColor(device, 160, 360);
979     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
980     color = getPixelColor(device, 160, 120);
981     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
982     color = getPixelColor(device, 480, 120);
983     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
984
985     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
986      * but without shaders it seems to work everywhere
987      */
988     end = 0.2;
989     start = 0.8;
990     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
991     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
993     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
994     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
995     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
996
997     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
998      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
999      * so skip this for now
1000      */
1001     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1002         const char *mode = (i ? "table" : "vertex");
1003         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1004         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1005         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1006         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1007         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1008         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1009         hr = IDirect3DDevice9_BeginScene(device);
1010         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1011         if(SUCCEEDED(hr)) {
1012             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1013                                 4,  5,  6,  6,  7, 4,
1014                                 8,  9, 10, 10, 11, 8,
1015                             12, 13, 14, 14, 15, 12};
1016
1017             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1018                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1019                     sizeof(rev_fog_quads[0]));
1020
1021             hr = IDirect3DDevice9_EndScene(device);
1022             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1023         }
1024         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1025         color = getPixelColor(device, 160, 360);
1026         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
1027
1028         color = getPixelColor(device, 160, 120);
1029         r = (color & 0x00ff0000) >> 16;
1030         g = (color & 0x0000ff00) >>  8;
1031         b = (color & 0x000000ff);
1032         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
1033            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
1034
1035         color = getPixelColor(device, 480, 120);
1036         r = (color & 0x00ff0000) >> 16;
1037         g = (color & 0x0000ff00) >>  8;
1038         b = (color & 0x000000ff);
1039         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
1040            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
1041
1042         color = getPixelColor(device, 480, 360);
1043         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1044
1045         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1046             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1047             break;
1048         }
1049     }
1050     /* Turn off the fog master switch to avoid confusing other tests */
1051     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1052     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1053     start = 0.0;
1054     end = 1.0;
1055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1056     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1057     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1058     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1059     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1060     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1061     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1062     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1063 }
1064
1065 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1066  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1067  * regardless of the actual addressing mode set. */
1068 static void test_cube_wrap(IDirect3DDevice9 *device)
1069 {
1070     static const float quad[][6] = {
1071         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1072         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1073         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1074         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1075     };
1076
1077     static const D3DVERTEXELEMENT9 decl_elements[] = {
1078         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1079         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1080         D3DDECL_END()
1081     };
1082
1083     static const struct {
1084         D3DTEXTUREADDRESS mode;
1085         const char *name;
1086     } address_modes[] = {
1087         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1088         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1089         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1090         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1091         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1092     };
1093
1094     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1095     IDirect3DCubeTexture9 *texture = NULL;
1096     IDirect3DSurface9 *surface = NULL;
1097     D3DLOCKED_RECT locked_rect;
1098     HRESULT hr;
1099     UINT x;
1100     INT y, face;
1101
1102     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1103     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1104     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1105     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1106
1107     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1108             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1109     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1110
1111     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1112     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1113
1114     for (y = 0; y < 128; ++y)
1115     {
1116         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1117         for (x = 0; x < 64; ++x)
1118         {
1119             *ptr++ = 0xffff0000;
1120         }
1121         for (x = 64; x < 128; ++x)
1122         {
1123             *ptr++ = 0xff0000ff;
1124         }
1125     }
1126
1127     hr = IDirect3DSurface9_UnlockRect(surface);
1128     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1129
1130     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1131             D3DPOOL_DEFAULT, &texture, NULL);
1132     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1133
1134     /* Create cube faces */
1135     for (face = 0; face < 6; ++face)
1136     {
1137         IDirect3DSurface9 *face_surface = NULL;
1138
1139         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1140         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1141
1142         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1143         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1144
1145         IDirect3DSurface9_Release(face_surface);
1146     }
1147
1148     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1149     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1150
1151     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1152     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1153     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1154     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1155     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1156     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1157
1158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1159     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1160
1161     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1162     {
1163         DWORD color;
1164
1165         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1166         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1167         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1168         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1169
1170         hr = IDirect3DDevice9_BeginScene(device);
1171         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1172
1173         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1174         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1175
1176         hr = IDirect3DDevice9_EndScene(device);
1177         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1178
1179         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1180         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1181
1182         /* Due to the nature of this test, we sample essentially at the edge
1183          * between two faces. Because of this it's undefined from which face
1184          * the driver will sample. Fortunately that's not important for this
1185          * test, since all we care about is that it doesn't sample from the
1186          * other side of the surface or from the border. */
1187         color = getPixelColor(device, 320, 240);
1188         ok(color == 0x00ff0000 || color == 0x000000ff,
1189                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1190                 color, address_modes[x].name);
1191
1192         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1193         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1194     }
1195
1196     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1197     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1198
1199     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1200     IDirect3DCubeTexture9_Release(texture);
1201     IDirect3DSurface9_Release(surface);
1202 }
1203
1204 static void offscreen_test(IDirect3DDevice9 *device)
1205 {
1206     HRESULT hr;
1207     IDirect3DTexture9 *offscreenTexture = NULL;
1208     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1209     DWORD color;
1210
1211     static const float quad[][5] = {
1212         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1213         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1214         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1215         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1216     };
1217
1218     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1219     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1220
1221     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1222     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1223     if(!offscreenTexture) {
1224         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1225         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1226         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1227         if(!offscreenTexture) {
1228             skip("Cannot create an offscreen render target\n");
1229             goto out;
1230         }
1231     }
1232
1233     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1234     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1235     if(!backbuffer) {
1236         goto out;
1237     }
1238
1239     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1240     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1241     if(!offscreen) {
1242         goto out;
1243     }
1244
1245     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1246     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1247
1248     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1249     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1250     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1251     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1252     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1253     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1254     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1255     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1256     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1257     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1258
1259     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1260         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1261         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1262         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1263         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1264
1265         /* Draw without textures - Should result in a white quad */
1266         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1267         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1268
1269         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1270         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1271         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1272         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1273
1274         /* This time with the texture */
1275         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1276         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1277
1278         IDirect3DDevice9_EndScene(device);
1279     }
1280
1281     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1282
1283     /* Center quad - should be white */
1284     color = getPixelColor(device, 320, 240);
1285     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1286     /* Some quad in the cleared part of the texture */
1287     color = getPixelColor(device, 170, 240);
1288     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1289     /* Part of the originally cleared back buffer */
1290     color = getPixelColor(device, 10, 10);
1291     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1292     if(0) {
1293         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1294          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1295          * the offscreen rendering mode this test would succeed or fail
1296          */
1297         color = getPixelColor(device, 10, 470);
1298         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1299     }
1300
1301 out:
1302     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1303
1304     /* restore things */
1305     if(backbuffer) {
1306         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1307         IDirect3DSurface9_Release(backbuffer);
1308     }
1309     if(offscreenTexture) {
1310         IDirect3DTexture9_Release(offscreenTexture);
1311     }
1312     if(offscreen) {
1313         IDirect3DSurface9_Release(offscreen);
1314     }
1315 }
1316
1317 /* This test tests fog in combination with shaders.
1318  * What's tested: linear fog (vertex and table) with pixel shader
1319  *                linear table fog with non foggy vertex shader
1320  *                vertex fog with foggy vertex shader
1321  * What's not tested: non linear fog with shader
1322  *                    table fog with foggy vertex shader
1323  */
1324 static void fog_with_shader_test(IDirect3DDevice9 *device)
1325 {
1326     HRESULT hr;
1327     DWORD color;
1328     union {
1329         float f;
1330         DWORD i;
1331     } start, end;
1332     unsigned int i, j;
1333
1334     /* basic vertex shader without fog computation ("non foggy") */
1335     static const DWORD vertex_shader_code1[] = {
1336         0xfffe0101,                                                             /* vs_1_1                       */
1337         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1338         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1339         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1340         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1341         0x0000ffff
1342     };
1343     /* basic vertex shader with reversed fog computation ("foggy") */
1344     static const DWORD vertex_shader_code2[] = {
1345         0xfffe0101,                                                             /* vs_1_1                        */
1346         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1347         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1348         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1349         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1350         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1351         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1352         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1353         0x0000ffff
1354     };
1355     /* basic pixel shader */
1356     static const DWORD pixel_shader_code[] = {
1357         0xffff0101,                                                             /* ps_1_1     */
1358         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1359         0x0000ffff
1360     };
1361
1362     static struct vertex quad[] = {
1363         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1364         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1365         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1366         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1367     };
1368
1369     static const D3DVERTEXELEMENT9 decl_elements[] = {
1370         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1371         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1372         D3DDECL_END()
1373     };
1374
1375     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1376     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1377     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1378
1379     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1380     static const struct test_data_t {
1381         int vshader;
1382         int pshader;
1383         D3DFOGMODE vfog;
1384         D3DFOGMODE tfog;
1385         unsigned int color[11];
1386     } test_data[] = {
1387         /* only pixel shader: */
1388         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1389         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1390         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1391         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1392         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1395         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1398         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1401         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1402         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1403
1404         /* vertex shader */
1405         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1406         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1407          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1408         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1409         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1410         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1411         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1412         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414
1415         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1416         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1417         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1419         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421
1422         /* vertex shader and pixel shader */
1423         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1424         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1425         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1426         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1427         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1428         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1429         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1430         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1431         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1432
1433         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1434         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1435         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1436
1437
1438 #if 0  /* FIXME: these fail on GeForce 8500 */
1439         /* foggy vertex shader */
1440         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1441         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1442          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1443         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1444         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1445          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1446         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1447         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1448          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1449         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1450         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1451          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1452 #endif
1453
1454         /* foggy vertex shader and pixel shader */
1455         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1456         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1457          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1458         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1459         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1460          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1461         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1462         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1463          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1464         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1465         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467
1468     };
1469
1470     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1471     start.f=0.1f;
1472     end.f=0.9f;
1473
1474     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1475     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1476     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1477     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1478     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1479     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1480     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1481     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1482
1483     /* Setup initial states: No lighting, fog on, fog color */
1484     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1485     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1486     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1487     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1488     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1489     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1490     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1491     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1492
1493     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1494     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1495     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1496     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1497
1498     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1499     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1500     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1501     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1502     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1503
1504     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1505     {
1506         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1507         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1508         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1509         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1510         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1511         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1512         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1513         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1514
1515         for(j=0; j < 11; j++)
1516         {
1517             /* Don't use the whole zrange to prevent rounding errors */
1518             quad[0].z = 0.001f + (float)j / 10.02f;
1519             quad[1].z = 0.001f + (float)j / 10.02f;
1520             quad[2].z = 0.001f + (float)j / 10.02f;
1521             quad[3].z = 0.001f + (float)j / 10.02f;
1522
1523             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1524             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1525
1526             hr = IDirect3DDevice9_BeginScene(device);
1527             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1528
1529             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1530             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1531
1532             hr = IDirect3DDevice9_EndScene(device);
1533             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1534
1535             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1536
1537             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1538             color = getPixelColor(device, 128, 240);
1539             if(test_data[i].vshader == 1 && test_data[i].tfog == 0 && color != test_data[i].color[j]) {
1540                 todo_wine ok(color_match(color, test_data[i].color[j], 13),
1541                              "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%(todo)\n",
1542                              test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1543             } else {
1544                 ok(color_match(color, test_data[i].color[j], 13),
1545                    "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1546                    test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1547             }
1548         }
1549     }
1550
1551     /* reset states */
1552     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1553     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1554     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1555     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1556     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1557     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1558     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1559     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1560
1561     IDirect3DVertexShader9_Release(vertex_shader[1]);
1562     IDirect3DVertexShader9_Release(vertex_shader[2]);
1563     IDirect3DPixelShader9_Release(pixel_shader[1]);
1564     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1565 }
1566
1567 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1568     unsigned int i, x, y;
1569     HRESULT hr;
1570     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1571     D3DLOCKED_RECT locked_rect;
1572
1573     /* Generate the textures */
1574     for(i=0; i<2; i++)
1575     {
1576         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1577                                             D3DPOOL_MANAGED, &texture[i], NULL);
1578         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1579
1580         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1581         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1582         for (y = 0; y < 128; ++y)
1583         {
1584             if(i)
1585             { /* Set up black texture with 2x2 texel white spot in the middle */
1586                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1587                 for (x = 0; x < 128; ++x)
1588                 {
1589                     if(y>62 && y<66 && x>62 && x<66)
1590                         *ptr++ = 0xffffffff;
1591                     else
1592                         *ptr++ = 0xff000000;
1593                 }
1594             }
1595             else
1596             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1597                * (if multiplied with bumpenvmat)
1598               */
1599                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1600                 for (x = 0; x < 128; ++x)
1601                 {
1602                     if(abs(x-64)>abs(y-64))
1603                     {
1604                         if(x < 64)
1605                             *ptr++ = 0xc000;
1606                         else
1607                             *ptr++ = 0x4000;
1608                     }
1609                     else
1610                     {
1611                         if(y < 64)
1612                             *ptr++ = 0x0040;
1613                         else
1614                             *ptr++ = 0x00c0;
1615                     }
1616                 }
1617             }
1618         }
1619         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1620         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1621
1622         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1623         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1624
1625         /* Disable texture filtering */
1626         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1627         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1628         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1629         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1630
1631         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1632         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1633         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1634         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1635     }
1636 }
1637
1638 /* test the behavior of the texbem instruction
1639  * with normal 2D and projective 2D textures
1640  */
1641 static void texbem_test(IDirect3DDevice9 *device)
1642 {
1643     HRESULT hr;
1644     DWORD color;
1645     int i;
1646
1647     static const DWORD pixel_shader_code[] = {
1648         0xffff0101,                         /* ps_1_1*/
1649         0x00000042, 0xb00f0000,             /* tex t0*/
1650         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1651         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1652         0x0000ffff
1653     };
1654     static const DWORD double_texbem_code[] =  {
1655         0xffff0103,                                         /* ps_1_3           */
1656         0x00000042, 0xb00f0000,                             /* tex t0           */
1657         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1658         0x00000042, 0xb00f0002,                             /* tex t2           */
1659         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1660         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1661         0x0000ffff                                          /* end              */
1662     };
1663
1664
1665     static const float quad[][7] = {
1666         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1667         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1668         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1669         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1670     };
1671     static const float quad_proj[][9] = {
1672         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1673         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1674         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1675         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1676     };
1677
1678     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1679         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1680         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1681         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1682         D3DDECL_END()
1683     },{
1684         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1685         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1686         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1687         D3DDECL_END()
1688     } };
1689
1690     /* use asymmetric matrix to test loading */
1691     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1692
1693     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1694     IDirect3DPixelShader9       *pixel_shader       = NULL;
1695     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1696     D3DLOCKED_RECT locked_rect;
1697
1698     generate_bumpmap_textures(device);
1699
1700     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1701     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1702     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1703     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1704     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1705
1706     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1707     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1708
1709     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1710     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1711
1712     for(i=0; i<2; i++)
1713     {
1714         if(i)
1715         {
1716             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1717             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1718         }
1719
1720         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1721         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1722         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1723         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1724
1725         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1726         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1727         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1728         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1729
1730         hr = IDirect3DDevice9_BeginScene(device);
1731         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1732
1733         if(!i)
1734             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1735         else
1736             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1737         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1738
1739         hr = IDirect3DDevice9_EndScene(device);
1740         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1741
1742         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1743         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1744
1745         color = getPixelColor(device, 320-32, 240);
1746         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1747         color = getPixelColor(device, 320+32, 240);
1748         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1749         color = getPixelColor(device, 320, 240-32);
1750         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1751         color = getPixelColor(device, 320, 240+32);
1752         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1753
1754         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1755         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1756         IDirect3DPixelShader9_Release(pixel_shader);
1757
1758         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1759         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1760         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1761     }
1762
1763     /* clean up */
1764     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1765     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1766
1767     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1768     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1769
1770     for(i=0; i<2; i++)
1771     {
1772         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1773         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1774         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1775         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1776         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1777         IDirect3DTexture9_Release(texture);
1778     }
1779
1780     /* Test double texbem */
1781     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1782     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1783     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1784     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1785     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1786     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1787     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1788     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1789
1790     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1791     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1792     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1793     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1794
1795     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1796     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1797
1798     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1799     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1800     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1801     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1802     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1803     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1804
1805     {
1806         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1807 #define tex  0x00ff0000
1808 #define tex1 0x0000ff00
1809 #define origin 0x000000ff
1810         static const DWORD pixel_data[] = {
1811             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1812             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1813             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1814             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1815             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1816             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1817             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1818             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1819         };
1820 #undef tex1
1821 #undef tex2
1822 #undef origin
1823
1824         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1825         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1826         for(i = 0; i < 8; i++) {
1827             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1828         }
1829         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1830         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1831     }
1832
1833     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1834     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1835     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1836     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1837     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1838     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1839     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1840     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1841     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1842     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1843     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1844     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1845
1846     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1847     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1848     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1849     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1850     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1851     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1852
1853     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1854     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1855     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1856     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1857     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1858     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1859
1860     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1861     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1862     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1863     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1864     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1865     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1866     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1867     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1868
1869     hr = IDirect3DDevice9_BeginScene(device);
1870     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1871     if(SUCCEEDED(hr)) {
1872         static const float double_quad[] = {
1873             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1874              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1875             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1876              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1877         };
1878
1879         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1880         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1881         hr = IDirect3DDevice9_EndScene(device);
1882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1883     }
1884     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1885     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1886     color = getPixelColor(device, 320, 240);
1887     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1888
1889     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1890     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1891     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1892     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1893     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1894     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1895     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1896     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1897     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1898     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1899
1900     IDirect3DPixelShader9_Release(pixel_shader);
1901     IDirect3DTexture9_Release(texture);
1902     IDirect3DTexture9_Release(texture1);
1903     IDirect3DTexture9_Release(texture2);
1904 }
1905
1906 static void z_range_test(IDirect3DDevice9 *device)
1907 {
1908     const struct vertex quad[] =
1909     {
1910         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1911         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1912         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1913         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1914     };
1915     const struct vertex quad2[] =
1916     {
1917         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1918         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1919         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1920         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1921     };
1922
1923     const struct tvertex quad3[] =
1924     {
1925         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1926         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1927         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1928         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1929     };
1930     const struct tvertex quad4[] =
1931     {
1932         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1933         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1934         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1935         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1936     };
1937     HRESULT hr;
1938     DWORD color;
1939     IDirect3DVertexShader9 *shader;
1940     IDirect3DVertexDeclaration9 *decl;
1941     D3DCAPS9 caps;
1942     const DWORD shader_code[] = {
1943         0xfffe0101,                                     /* vs_1_1           */
1944         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1945         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1946         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1947         0x0000ffff                                      /* end              */
1948     };
1949     static const D3DVERTEXELEMENT9 decl_elements[] = {
1950         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1951         D3DDECL_END()
1952     };
1953     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1954      * then call Present. Then clear the color buffer to make sure it has some defined content
1955      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1956      * by the depth value.
1957      */
1958     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1959     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1960     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1961     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1962
1963     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1964     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1965     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1966     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1967     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1968     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1969     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1970     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1971     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1972     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1973
1974     hr = IDirect3DDevice9_BeginScene(device);
1975     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1976     if(hr == D3D_OK)
1977     {
1978         /* Test the untransformed vertex path */
1979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1980         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1981         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1982         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1984         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1985
1986         /* Test the transformed vertex path */
1987         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1988         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1989
1990         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1991         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1992         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1993         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1994         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1995         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1996
1997         hr = IDirect3DDevice9_EndScene(device);
1998         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1999     }
2000
2001     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2002     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2003
2004     /* Do not test the exact corner pixels, but go pretty close to them */
2005
2006     /* Clipped because z > 1.0 */
2007     color = getPixelColor(device, 28, 238);
2008     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2009     color = getPixelColor(device, 28, 241);
2010     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2011
2012     /* Not clipped, > z buffer clear value(0.75) */
2013     color = getPixelColor(device, 31, 238);
2014     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2015     color = getPixelColor(device, 31, 241);
2016     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2017     color = getPixelColor(device, 100, 238);
2018     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2019     color = getPixelColor(device, 100, 241);
2020     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2021
2022     /* Not clipped, < z buffer clear value */
2023     color = getPixelColor(device, 104, 238);
2024     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2025     color = getPixelColor(device, 104, 241);
2026     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2027     color = getPixelColor(device, 318, 238);
2028     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2029     color = getPixelColor(device, 318, 241);
2030     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2031
2032     /* Clipped because z < 0.0 */
2033     color = getPixelColor(device, 321, 238);
2034     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2035     color = getPixelColor(device, 321, 241);
2036     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2037
2038     /* Test the shader path */
2039     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2040     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2041         skip("Vertex shaders not supported\n");
2042         goto out;
2043     }
2044     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2045     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2046     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2047     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2048
2049     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2050
2051     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2052     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2053     IDirect3DDevice9_SetVertexShader(device, shader);
2054     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2055
2056     hr = IDirect3DDevice9_BeginScene(device);
2057     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2058     if(hr == D3D_OK)
2059     {
2060         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2061         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2062         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2063         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2064         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2065         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2066         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2067         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2068         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2069         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2070
2071         hr = IDirect3DDevice9_EndScene(device);
2072         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2073     }
2074
2075     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2076     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2077     IDirect3DDevice9_SetVertexShader(device, NULL);
2078     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2079
2080     IDirect3DVertexDeclaration9_Release(decl);
2081     IDirect3DVertexShader9_Release(shader);
2082
2083     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2084     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2085     /* Z < 1.0 */
2086     color = getPixelColor(device, 28, 238);
2087     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2088
2089     /* 1.0 < z < 0.75 */
2090     color = getPixelColor(device, 31, 238);
2091     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2092     color = getPixelColor(device, 100, 238);
2093     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2094
2095     /* 0.75 < z < 0.0 */
2096     color = getPixelColor(device, 104, 238);
2097     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2098     color = getPixelColor(device, 318, 238);
2099     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2100
2101     /* 0.0 < z */
2102     color = getPixelColor(device, 321, 238);
2103     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2104
2105     out:
2106     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2107     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2108     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2109     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2110     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2111     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2112 }
2113
2114 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2115 {
2116     D3DSURFACE_DESC desc;
2117     D3DLOCKED_RECT l;
2118     HRESULT hr;
2119     unsigned int x, y;
2120     DWORD *mem;
2121
2122     memset(&desc, 0, sizeof(desc));
2123     memset(&l, 0, sizeof(l));
2124     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2125     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2126     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2127     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2128     if(FAILED(hr)) return;
2129
2130     for(y = 0; y < desc.Height; y++)
2131     {
2132         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2133         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2134         {
2135             mem[x] = color;
2136         }
2137     }
2138     hr = IDirect3DSurface9_UnlockRect(surface);
2139     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2140 }
2141
2142 /* This tests a variety of possible StretchRect() situations */
2143 static void stretchrect_test(IDirect3DDevice9 *device)
2144 {
2145     HRESULT hr;
2146     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2147     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2148     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2149     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2150     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2151     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2152     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2153     IDirect3DSurface9 *orig_rt = NULL;
2154     DWORD color;
2155
2156     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2157     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2158     if(!orig_rt) {
2159         goto out;
2160     }
2161
2162     /* Create our temporary surfaces in system memory */
2163     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2164     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2165     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2166     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2167
2168     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2169     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2170     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2171     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2172     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2173     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2174     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2175
2176     /* Create render target surfaces */
2177     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2178     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2179     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2180     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2181     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2182     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2183
2184     /* Create render target textures */
2185     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2186     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2187     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2188     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2189     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2190     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2191     if (tex_rt32) {
2192         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2193         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2194     }
2195     if (tex_rt64) {
2196         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2197         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2198     }
2199     if (tex_rt_dest64) {
2200         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2201         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2202     }
2203
2204     /* Create regular textures in D3DPOOL_DEFAULT */
2205     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2206     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2207     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2208     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2209     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2210     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2211     if (tex32) {
2212         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2213         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2214     }
2215     if (tex64) {
2216         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2217         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2218     }
2219     if (tex_dest64) {
2220         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2221         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2222     }
2223
2224     /*********************************************************************
2225      * Tests for when the source parameter is an offscreen plain surface *
2226      *********************************************************************/
2227
2228     /* Fill the offscreen 64x64 surface with green */
2229     if (surf_offscreen64)
2230         fill_surface(surf_offscreen64, 0xff00ff00);
2231
2232     /* offscreenplain ==> offscreenplain, same size */
2233     if(surf_offscreen64 && surf_offscreen_dest64) {
2234         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2235         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2236
2237         if (hr == D3D_OK) {
2238             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2239             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2240         }
2241     }
2242
2243     /* offscreenplain ==> rendertarget texture, same size */
2244     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2245         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2246         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2247
2248         /* We can't lock rendertarget textures, so copy to our temp surface first */
2249         if (hr == D3D_OK) {
2250             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2251             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2252         }
2253
2254         if (hr == D3D_OK) {
2255             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2256             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2257         }
2258     }
2259
2260     /* offscreenplain ==> rendertarget surface, same size */
2261     if(surf_offscreen64 && surf_rt_dest64) {
2262         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2263         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2264
2265         if (hr == D3D_OK) {
2266             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2267             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2268         }
2269     }
2270
2271     /* offscreenplain ==> texture, same size (should fail) */
2272     if(surf_offscreen64 && surf_tex_dest64) {
2273         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2274         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2275     }
2276
2277     /* Fill the smaller offscreen surface with red */
2278     fill_surface(surf_offscreen32, 0xffff0000);
2279
2280     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2281     if(surf_offscreen32 && surf_offscreen64) {
2282         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2283         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2284     }
2285
2286     /* offscreenplain ==> rendertarget texture, scaling */
2287     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2288         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2289         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2290
2291         /* We can't lock rendertarget textures, so copy to our temp surface first */
2292         if (hr == D3D_OK) {
2293             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2294             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2295         }
2296
2297         if (hr == D3D_OK) {
2298             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2299             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2300         }
2301     }
2302
2303     /* offscreenplain ==> rendertarget surface, scaling */
2304     if(surf_offscreen32 && surf_rt_dest64) {
2305         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2306         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2307
2308         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2309         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2310     }
2311
2312     /* offscreenplain ==> texture, scaling (should fail) */
2313     if(surf_offscreen32 && surf_tex_dest64) {
2314         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2315         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2316     }
2317
2318     /************************************************************
2319      * Tests for when the source parameter is a regular texture *
2320      ************************************************************/
2321
2322     /* Fill the surface of the regular texture with blue */
2323     if (surf_tex64 && surf_temp64) {
2324         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2325         fill_surface(surf_temp64, 0xff0000ff);
2326         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2327         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2328     }
2329
2330     /* texture ==> offscreenplain, same size */
2331     if(surf_tex64 && surf_offscreen64) {
2332         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2333         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2334     }
2335
2336     /* texture ==> rendertarget texture, same size */
2337     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2338         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2339         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2340
2341         /* We can't lock rendertarget textures, so copy to our temp surface first */
2342         if (hr == D3D_OK) {
2343             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2344             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2345         }
2346
2347         if (hr == D3D_OK) {
2348             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2349             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2350         }
2351     }
2352
2353     /* texture ==> rendertarget surface, same size */
2354     if(surf_tex64 && surf_rt_dest64) {
2355         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2356         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2357
2358         if (hr == D3D_OK) {
2359             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2360             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2361         }
2362     }
2363
2364     /* texture ==> texture, same size (should fail) */
2365     if(surf_tex64 && surf_tex_dest64) {
2366         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2367         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2368     }
2369
2370     /* Fill the surface of the smaller regular texture with red */
2371     if (surf_tex32 && surf_temp32) {
2372         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2373         fill_surface(surf_temp32, 0xffff0000);
2374         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2375         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2376     }
2377
2378     /* texture ==> offscreenplain, scaling (should fail) */
2379     if(surf_tex32 && surf_offscreen64) {
2380         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2381         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2382     }
2383
2384     /* texture ==> rendertarget texture, scaling */
2385     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2386         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2387         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2388
2389         /* We can't lock rendertarget textures, so copy to our temp surface first */
2390         if (hr == D3D_OK) {
2391             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2392             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2393         }
2394
2395         if (hr == D3D_OK) {
2396             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2397             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2398         }
2399     }
2400
2401     /* texture ==> rendertarget surface, scaling */
2402     if(surf_tex32 && surf_rt_dest64) {
2403         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2404         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2405
2406         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2407         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2408     }
2409
2410     /* texture ==> texture, scaling (should fail) */
2411     if(surf_tex32 && surf_tex_dest64) {
2412         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2413         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2414     }
2415
2416     /*****************************************************************
2417      * Tests for when the source parameter is a rendertarget texture *
2418      *****************************************************************/
2419
2420     /* Fill the surface of the rendertarget texture with white */
2421     if (surf_tex_rt64 && surf_temp64) {
2422         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2423         fill_surface(surf_temp64, 0xffffffff);
2424         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2425         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2426     }
2427
2428     /* rendertarget texture ==> offscreenplain, same size */
2429     if(surf_tex_rt64 && surf_offscreen64) {
2430         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2431         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2432     }
2433
2434     /* rendertarget texture ==> rendertarget texture, same size */
2435     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2436         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2437         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2438
2439         /* We can't lock rendertarget textures, so copy to our temp surface first */
2440         if (hr == D3D_OK) {
2441             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2442             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2443         }
2444
2445         if (hr == D3D_OK) {
2446             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2447             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2448         }
2449     }
2450
2451     /* rendertarget texture ==> rendertarget surface, same size */
2452     if(surf_tex_rt64 && surf_rt_dest64) {
2453         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2454         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2455
2456         if (hr == D3D_OK) {
2457             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2458             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2459         }
2460     }
2461
2462     /* rendertarget texture ==> texture, same size (should fail) */
2463     if(surf_tex_rt64 && surf_tex_dest64) {
2464         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2465         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2466     }
2467
2468     /* Fill the surface of the smaller rendertarget texture with red */
2469     if (surf_tex_rt32 && surf_temp32) {
2470         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2471         fill_surface(surf_temp32, 0xffff0000);
2472         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2473         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2474     }
2475
2476     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2477     if(surf_tex_rt32 && surf_offscreen64) {
2478         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2479         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2480     }
2481
2482     /* rendertarget texture ==> rendertarget texture, scaling */
2483     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2484         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2485         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2486
2487         /* We can't lock rendertarget textures, so copy to our temp surface first */
2488         if (hr == D3D_OK) {
2489             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2490             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2491         }
2492
2493         if (hr == D3D_OK) {
2494             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2495             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2496         }
2497     }
2498
2499     /* rendertarget texture ==> rendertarget surface, scaling */
2500     if(surf_tex_rt32 && surf_rt_dest64) {
2501         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2502         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2503
2504         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2505         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2506     }
2507
2508     /* rendertarget texture ==> texture, scaling (should fail) */
2509     if(surf_tex_rt32 && surf_tex_dest64) {
2510         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2511         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2512     }
2513
2514     /*****************************************************************
2515      * Tests for when the source parameter is a rendertarget surface *
2516      *****************************************************************/
2517
2518     /* Fill the surface of the rendertarget surface with black */
2519     if (surf_rt64)
2520         fill_surface(surf_rt64, 0xff000000);
2521
2522     /* rendertarget texture ==> offscreenplain, same size */
2523     if(surf_rt64 && surf_offscreen64) {
2524         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2525         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2526     }
2527
2528     /* rendertarget surface ==> rendertarget texture, same size */
2529     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2530         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2531         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2532
2533         /* We can't lock rendertarget textures, so copy to our temp surface first */
2534         if (hr == D3D_OK) {
2535             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2536             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2537         }
2538
2539         if (hr == D3D_OK) {
2540             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2541             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2542         }
2543     }
2544
2545     /* rendertarget surface ==> rendertarget surface, same size */
2546     if(surf_rt64 && surf_rt_dest64) {
2547         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2548         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2549
2550         if (hr == D3D_OK) {
2551             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2552             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2553         }
2554     }
2555
2556     /* rendertarget surface ==> texture, same size (should fail) */
2557     if(surf_rt64 && surf_tex_dest64) {
2558         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2559         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2560     }
2561
2562     /* Fill the surface of the smaller rendertarget texture with red */
2563     if (surf_rt32)
2564         fill_surface(surf_rt32, 0xffff0000);
2565
2566     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2567     if(surf_rt32 && surf_offscreen64) {
2568         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2569         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2570     }
2571
2572     /* rendertarget surface ==> rendertarget texture, scaling */
2573     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2574         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2575         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2576
2577         /* We can't lock rendertarget textures, so copy to our temp surface first */
2578         if (hr == D3D_OK) {
2579             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2580             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2581         }
2582
2583         if (hr == D3D_OK) {
2584             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2585             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2586         }
2587     }
2588
2589     /* rendertarget surface ==> rendertarget surface, scaling */
2590     if(surf_rt32 && surf_rt_dest64) {
2591         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2592         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2593
2594         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2595         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2596     }
2597
2598     /* rendertarget surface ==> texture, scaling (should fail) */
2599     if(surf_rt32 && surf_tex_dest64) {
2600         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2601         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2602     }
2603
2604     /* TODO: Test when source and destination RECT parameters are given... */
2605     /* TODO: Test format conversions */
2606
2607
2608 out:
2609     /* Clean up */
2610     if (surf_rt32)
2611         IDirect3DSurface9_Release(surf_rt32);
2612     if (surf_rt64)
2613         IDirect3DSurface9_Release(surf_rt64);
2614     if (surf_rt_dest64)
2615         IDirect3DSurface9_Release(surf_rt_dest64);
2616     if (surf_temp32)
2617         IDirect3DSurface9_Release(surf_temp32);
2618     if (surf_temp64)
2619         IDirect3DSurface9_Release(surf_temp64);
2620     if (surf_offscreen32)
2621         IDirect3DSurface9_Release(surf_offscreen32);
2622     if (surf_offscreen64)
2623         IDirect3DSurface9_Release(surf_offscreen64);
2624     if (surf_offscreen_dest64)
2625         IDirect3DSurface9_Release(surf_offscreen_dest64);
2626
2627     if (tex_rt32) {
2628         if (surf_tex_rt32)
2629             IDirect3DSurface9_Release(surf_tex_rt32);
2630         IDirect3DTexture9_Release(tex_rt32);
2631     }
2632     if (tex_rt64) {
2633         if (surf_tex_rt64)
2634             IDirect3DSurface9_Release(surf_tex_rt64);
2635         IDirect3DTexture9_Release(tex_rt64);
2636     }
2637     if (tex_rt_dest64) {
2638         if (surf_tex_rt_dest64)
2639             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2640         IDirect3DTexture9_Release(tex_rt_dest64);
2641     }
2642     if (tex32) {
2643         if (surf_tex32)
2644             IDirect3DSurface9_Release(surf_tex32);
2645         IDirect3DTexture9_Release(tex32);
2646     }
2647     if (tex64) {
2648         if (surf_tex64)
2649             IDirect3DSurface9_Release(surf_tex64);
2650         IDirect3DTexture9_Release(tex64);
2651     }
2652     if (tex_dest64) {
2653         if (surf_tex_dest64)
2654             IDirect3DSurface9_Release(surf_tex_dest64);
2655         IDirect3DTexture9_Release(tex_dest64);
2656     }
2657
2658     if (orig_rt) {
2659         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2660         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2661         IDirect3DSurface9_Release(orig_rt);
2662     }
2663 }
2664
2665 static void maxmip_test(IDirect3DDevice9 *device)
2666 {
2667     IDirect3DTexture9 *texture = NULL;
2668     IDirect3DSurface9 *surface = NULL;
2669     HRESULT hr;
2670     DWORD color;
2671     const float quads[] = {
2672         -1.0,   -1.0,   0.0,    0.0,    0.0,
2673         -1.0,    0.0,   0.0,    0.0,    1.0,
2674          0.0,   -1.0,   0.0,    1.0,    0.0,
2675          0.0,    0.0,   0.0,    1.0,    1.0,
2676
2677          0.0,   -1.0,   0.0,    0.0,    0.0,
2678          0.0,    0.0,   0.0,    0.0,    1.0,
2679          1.0,   -1.0,   0.0,    1.0,    0.0,
2680          1.0,    0.0,   0.0,    1.0,    1.0,
2681
2682          0.0,    0.0,   0.0,    0.0,    0.0,
2683          0.0,    1.0,   0.0,    0.0,    1.0,
2684          1.0,    0.0,   0.0,    1.0,    0.0,
2685          1.0,    1.0,   0.0,    1.0,    1.0,
2686
2687         -1.0,    0.0,   0.0,    0.0,    0.0,
2688         -1.0,    1.0,   0.0,    0.0,    1.0,
2689          0.0,    0.0,   0.0,    1.0,    0.0,
2690          0.0,    1.0,   0.0,    1.0,    1.0,
2691     };
2692
2693     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2694     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2695
2696     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2697                                         &texture, NULL);
2698     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2699     if(!texture)
2700     {
2701         skip("Failed to create test texture\n");
2702         return;
2703     }
2704
2705     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2706     fill_surface(surface, 0xffff0000);
2707     IDirect3DSurface9_Release(surface);
2708     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2709     fill_surface(surface, 0xff00ff00);
2710     IDirect3DSurface9_Release(surface);
2711     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2712     fill_surface(surface, 0xff0000ff);
2713     IDirect3DSurface9_Release(surface);
2714
2715     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2717     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2718     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2719
2720     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2721     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2722
2723     hr = IDirect3DDevice9_BeginScene(device);
2724     if(SUCCEEDED(hr))
2725     {
2726         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2727         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2728         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2729         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2730
2731         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2732         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2733         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2734         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2735
2736         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2737         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2738         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2739         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2740
2741         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2742         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2744         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2745         hr = IDirect3DDevice9_EndScene(device);
2746     }
2747
2748     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2749     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2750     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2751     color = getPixelColor(device, 160, 360);
2752     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2753     color = getPixelColor(device, 160, 120);
2754     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2755     color = getPixelColor(device, 480, 120);
2756     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2757     color = getPixelColor(device, 480, 360);
2758     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2759
2760     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2761     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2762
2763     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2764     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2765
2766     hr = IDirect3DDevice9_BeginScene(device);
2767     if(SUCCEEDED(hr))
2768     {
2769         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2770         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2772         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2773
2774         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2775         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2777         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2778
2779         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2780         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2781         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2782         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2783
2784         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2785         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2786         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2787         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2788         hr = IDirect3DDevice9_EndScene(device);
2789     }
2790
2791     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2792     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2793     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2794     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2795
2796     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2797     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2798     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2799      * samples from the highest level in the texture(level 2)
2800      */
2801     color = getPixelColor(device, 160, 360);
2802     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2803     color = getPixelColor(device, 160, 120);
2804     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2805     color = getPixelColor(device, 480, 120);
2806     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2807     color = getPixelColor(device, 480, 360);
2808     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2809
2810     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2811     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2812     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2813     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2814     IDirect3DTexture9_Release(texture);
2815 }
2816
2817 static void release_buffer_test(IDirect3DDevice9 *device)
2818 {
2819     IDirect3DVertexBuffer9 *vb = NULL;
2820     IDirect3DIndexBuffer9 *ib = NULL;
2821     HRESULT hr;
2822     BYTE *data;
2823     long ref;
2824
2825     static const struct vertex quad[] = {
2826         {-1.0,      -1.0,       0.1,        0xffff0000},
2827         {-1.0,       1.0,       0.1,        0xffff0000},
2828         { 1.0,       1.0,       0.1,        0xffff0000},
2829
2830         {-1.0,      -1.0,       0.1,        0xff00ff00},
2831         {-1.0,       1.0,       0.1,        0xff00ff00},
2832         { 1.0,       1.0,       0.1,        0xff00ff00}
2833     };
2834     short indices[] = {3, 4, 5};
2835
2836     /* Index and vertex buffers should always be creatable */
2837     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2838                                               D3DPOOL_MANAGED, &vb, NULL);
2839     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2840     if(!vb) {
2841         skip("Failed to create a vertex buffer\n");
2842         return;
2843     }
2844     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2845     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2846     if(!ib) {
2847         skip("Failed to create an index buffer\n");
2848         return;
2849     }
2850
2851     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2852     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2853     memcpy(data, quad, sizeof(quad));
2854     hr = IDirect3DVertexBuffer9_Unlock(vb);
2855     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2856
2857     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2858     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2859     memcpy(data, indices, sizeof(indices));
2860     hr = IDirect3DIndexBuffer9_Unlock(ib);
2861     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2862
2863     hr = IDirect3DDevice9_SetIndices(device, ib);
2864     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2865     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2866     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2867     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2868     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2869
2870     /* Now destroy the bound index buffer and draw again */
2871     ref = IDirect3DIndexBuffer9_Release(ib);
2872     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2873
2874     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2875     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2876
2877     hr = IDirect3DDevice9_BeginScene(device);
2878     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2879     if(SUCCEEDED(hr))
2880     {
2881         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2882          * making assumptions about the indices or vertices
2883          */
2884         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2885         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2886         hr = IDirect3DDevice9_EndScene(device);
2887         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2888     }
2889
2890     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2891     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2892
2893     hr = IDirect3DDevice9_SetIndices(device, NULL);
2894     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2895     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2896     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2897
2898     /* Index buffer was already destroyed as part of the test */
2899     IDirect3DVertexBuffer9_Release(vb);
2900 }
2901
2902 static void float_texture_test(IDirect3DDevice9 *device)
2903 {
2904     IDirect3D9 *d3d = NULL;
2905     HRESULT hr;
2906     IDirect3DTexture9 *texture = NULL;
2907     D3DLOCKED_RECT lr;
2908     float *data;
2909     DWORD color;
2910     float quad[] = {
2911         -1.0,      -1.0,       0.1,     0.0,    0.0,
2912         -1.0,       1.0,       0.1,     0.0,    1.0,
2913          1.0,      -1.0,       0.1,     1.0,    0.0,
2914          1.0,       1.0,       0.1,     1.0,    1.0,
2915     };
2916
2917     memset(&lr, 0, sizeof(lr));
2918     IDirect3DDevice9_GetDirect3D(device, &d3d);
2919     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2920                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2921         skip("D3DFMT_R32F textures not supported\n");
2922         goto out;
2923     }
2924
2925     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2926                                         D3DPOOL_MANAGED, &texture, NULL);
2927     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2928     if(!texture) {
2929         skip("Failed to create R32F texture\n");
2930         goto out;
2931     }
2932
2933     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2934     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2935     data = lr.pBits;
2936     *data = 0.0;
2937     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2938     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2939
2940     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2941     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2942
2943     hr = IDirect3DDevice9_BeginScene(device);
2944     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2945     if(SUCCEEDED(hr))
2946     {
2947         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2948         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2949
2950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2951         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2952
2953         hr = IDirect3DDevice9_EndScene(device);
2954         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2955     }
2956     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2957     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2958
2959     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2960     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2961
2962     color = getPixelColor(device, 240, 320);
2963     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2964
2965 out:
2966     if(texture) IDirect3DTexture9_Release(texture);
2967     IDirect3D9_Release(d3d);
2968 }
2969
2970 static void g16r16_texture_test(IDirect3DDevice9 *device)
2971 {
2972     IDirect3D9 *d3d = NULL;
2973     HRESULT hr;
2974     IDirect3DTexture9 *texture = NULL;
2975     D3DLOCKED_RECT lr;
2976     DWORD *data;
2977     DWORD color, red, green, blue;
2978     float quad[] = {
2979        -1.0,      -1.0,       0.1,     0.0,    0.0,
2980        -1.0,       1.0,       0.1,     0.0,    1.0,
2981         1.0,      -1.0,       0.1,     1.0,    0.0,
2982         1.0,       1.0,       0.1,     1.0,    1.0,
2983     };
2984
2985     memset(&lr, 0, sizeof(lr));
2986     IDirect3DDevice9_GetDirect3D(device, &d3d);
2987     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2988        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2989            skip("D3DFMT_G16R16 textures not supported\n");
2990            goto out;
2991     }
2992
2993     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2994                                         D3DPOOL_MANAGED, &texture, NULL);
2995     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2996     if(!texture) {
2997         skip("Failed to create D3DFMT_G16R16 texture\n");
2998         goto out;
2999     }
3000
3001     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3002     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3003     data = lr.pBits;
3004     *data = 0x0f00f000;
3005     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3006     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3007
3008     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3010
3011     hr = IDirect3DDevice9_BeginScene(device);
3012     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3013     if(SUCCEEDED(hr))
3014     {
3015         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3016         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3017
3018         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3019         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3020
3021         hr = IDirect3DDevice9_EndScene(device);
3022         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3023     }
3024     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3025     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3026
3027     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3028     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3029
3030     color = getPixelColor(device, 240, 320);
3031     red   = (color & 0x00ff0000) >> 16;
3032     green = (color & 0x0000ff00) >>  8;
3033     blue  = (color & 0x000000ff) >>  0;
3034     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3035        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3036
3037 out:
3038     if(texture) IDirect3DTexture9_Release(texture);
3039     IDirect3D9_Release(d3d);
3040 }
3041
3042 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3043 {
3044     HRESULT hr;
3045     IDirect3D9 *d3d;
3046     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3047     D3DCAPS9 caps;
3048     IDirect3DTexture9 *texture = NULL;
3049     IDirect3DVolumeTexture9 *volume = NULL;
3050     unsigned int x, y, z;
3051     D3DLOCKED_RECT lr;
3052     D3DLOCKED_BOX lb;
3053     DWORD color;
3054     UINT w, h;
3055     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3056     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3057                            0.0, 1.0, 0.0, 0.0,
3058                            0.0, 0.0, 1.0, 0.0,
3059                            0.0, 0.0, 0.0, 1.0};
3060     static const D3DVERTEXELEMENT9 decl_elements[] = {
3061         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3062         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3063         D3DDECL_END()
3064     };
3065     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3066         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3067         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3068         D3DDECL_END()
3069     };
3070     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3071         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3072         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3073         D3DDECL_END()
3074     };
3075     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3076                                                  0x00, 0xff, 0x00, 0x00,
3077                                                  0x00, 0x00, 0x00, 0x00,
3078                                                  0x00, 0x00, 0x00, 0x00};
3079
3080     memset(&lr, 0, sizeof(lr));
3081     memset(&lb, 0, sizeof(lb));
3082     IDirect3DDevice9_GetDirect3D(device, &d3d);
3083     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3084                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3085         fmt = D3DFMT_A16B16G16R16;
3086     }
3087     IDirect3D9_Release(d3d);
3088
3089     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3090     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3091     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3092     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3093     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3094     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3095     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3096     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3097     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3098     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3099     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3100     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3101     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3102     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3103     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3104     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3105     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3106     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3107     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3108     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3109     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3110     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3111     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3112     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3113
3114     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3115     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3116     w = min(1024, caps.MaxTextureWidth);
3117     h = min(1024, caps.MaxTextureHeight);
3118     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3119                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3120     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3121     if(!texture) {
3122         skip("Failed to create the test texture\n");
3123         return;
3124     }
3125
3126     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3127      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3128      * 1.0 in red and green for the x and y coords
3129      */
3130     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3131     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3132     for(y = 0; y < h; y++) {
3133         for(x = 0; x < w; x++) {
3134             double r_f = (double) y / (double) h;
3135             double g_f = (double) x / (double) w;
3136             if(fmt == D3DFMT_A16B16G16R16) {
3137                 unsigned short r, g;
3138                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3139                 r = (unsigned short) (r_f * 65536.0);
3140                 g = (unsigned short) (g_f * 65536.0);
3141                 dst[0] = r;
3142                 dst[1] = g;
3143                 dst[2] = 0;
3144                 dst[3] = 65535;
3145             } else {
3146                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3147                 unsigned char r = (unsigned char) (r_f * 255.0);
3148                 unsigned char g = (unsigned char) (g_f * 255.0);
3149                 dst[0] = 0;
3150                 dst[1] = g;
3151                 dst[2] = r;
3152                 dst[3] = 255;
3153             }
3154         }
3155     }
3156     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3157     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3158     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3159     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3160
3161     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3162     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3163     hr = IDirect3DDevice9_BeginScene(device);
3164     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3165     if(SUCCEEDED(hr))
3166     {
3167         float quad1[] = {
3168             -1.0,      -1.0,       0.1,     1.0,    1.0,
3169             -1.0,       0.0,       0.1,     1.0,    1.0,
3170              0.0,      -1.0,       0.1,     1.0,    1.0,
3171              0.0,       0.0,       0.1,     1.0,    1.0,
3172         };
3173         float quad2[] = {
3174             -1.0,       0.0,       0.1,     1.0,    1.0,
3175             -1.0,       1.0,       0.1,     1.0,    1.0,
3176              0.0,       0.0,       0.1,     1.0,    1.0,
3177              0.0,       1.0,       0.1,     1.0,    1.0,
3178         };
3179         float quad3[] = {
3180              0.0,       0.0,       0.1,     0.5,    0.5,
3181              0.0,       1.0,       0.1,     0.5,    0.5,
3182              1.0,       0.0,       0.1,     0.5,    0.5,
3183              1.0,       1.0,       0.1,     0.5,    0.5,
3184         };
3185         float quad4[] = {
3186              320,       480,       0.1,     1.0,    0.0,    1.0,
3187              320,       240,       0.1,     1.0,    0.0,    1.0,
3188              640,       480,       0.1,     1.0,    0.0,    1.0,
3189              640,       240,       0.1,     1.0,    0.0,    1.0,
3190         };
3191         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3192                           0.0, 0.0, 0.0, 0.0,
3193                           0.0, 0.0, 0.0, 0.0,
3194                           0.0, 0.0, 0.0, 0.0};
3195
3196         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3197         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3198         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3199         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3200         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3201
3202         /* What happens with transforms enabled? */
3203         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3204         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3205         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3206         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3207
3208         /* What happens if 4 coords are used, but only 2 given ?*/
3209         mat[8] = 1.0;
3210         mat[13] = 1.0;
3211         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3212         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3213         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3214         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3215         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3216         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3217
3218         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3219          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3220          * due to the coords in the vertices. (turns out red, indeed)
3221          */
3222         memset(mat, 0, sizeof(mat));
3223         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3224         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3225         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3226         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3227         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3228         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3230         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3231
3232         hr = IDirect3DDevice9_EndScene(device);
3233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3234     }
3235     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3236     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3237     color = getPixelColor(device, 160, 360);
3238     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3239     color = getPixelColor(device, 160, 120);
3240     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3241     color = getPixelColor(device, 480, 120);
3242     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3243     color = getPixelColor(device, 480, 360);
3244     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3245
3246     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3247     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3248
3249     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3250     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3251     hr = IDirect3DDevice9_BeginScene(device);
3252     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3253     if(SUCCEEDED(hr))
3254     {
3255         float quad1[] = {
3256             -1.0,      -1.0,       0.1,     0.8,    0.2,
3257             -1.0,       0.0,       0.1,     0.8,    0.2,
3258              0.0,      -1.0,       0.1,     0.8,    0.2,
3259              0.0,       0.0,       0.1,     0.8,    0.2,
3260         };
3261         float quad2[] = {
3262             -1.0,       0.0,       0.1,     0.5,    1.0,
3263             -1.0,       1.0,       0.1,     0.5,    1.0,
3264              0.0,       0.0,       0.1,     0.5,    1.0,
3265              0.0,       1.0,       0.1,     0.5,    1.0,
3266         };
3267         float quad3[] = {
3268              0.0,       0.0,       0.1,     0.5,    1.0,
3269              0.0,       1.0,       0.1,     0.5,    1.0,
3270              1.0,       0.0,       0.1,     0.5,    1.0,
3271              1.0,       1.0,       0.1,     0.5,    1.0,
3272         };
3273         float quad4[] = {
3274              0.0,      -1.0,       0.1,     0.8,    0.2,
3275              0.0,       0.0,       0.1,     0.8,    0.2,
3276              1.0,      -1.0,       0.1,     0.8,    0.2,
3277              1.0,       0.0,       0.1,     0.8,    0.2,
3278         };
3279         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3280                           0.0, 0.0, 0.0, 0.0,
3281                           0.0, 1.0, 0.0, 0.0,
3282                           0.0, 0.0, 0.0, 0.0};
3283
3284         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3285          */
3286         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3287         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3288         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3289         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3290
3291         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3292         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3293
3294         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3295          * it behaves like COUNT2 because normal textures require 2 coords
3296          */
3297         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3298         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3300         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3301
3302         /* Just to be sure, the same as quad2 above */
3303         memset(mat, 0, sizeof(mat));
3304         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3305         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3306         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3307         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3308         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3309         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3310
3311         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3312          * used? And what happens to the first?
3313          */
3314         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3315         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3317         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3318
3319         hr = IDirect3DDevice9_EndScene(device);
3320         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3321     }
3322     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3323     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3324     color = getPixelColor(device, 160, 360);
3325     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3326     color = getPixelColor(device, 160, 120);
3327     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3328     color = getPixelColor(device, 480, 120);
3329     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3330        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3331     color = getPixelColor(device, 480, 360);
3332     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3333        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3334
3335     IDirect3DTexture9_Release(texture);
3336
3337     /* Test projected textures, without any fancy matrices */
3338     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3339     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3340     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3341     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3342     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3343     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3344     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3345     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3346
3347     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3348     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3349     for(x = 0; x < 4; x++) {
3350         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3351     }
3352     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3353     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3354     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3355     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3356
3357     hr = IDirect3DDevice9_BeginScene(device);
3358     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3359     if(SUCCEEDED(hr))
3360     {
3361         const float proj_quads[] = {
3362            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3363             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3364            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3365             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3366            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3367             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3368            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3369             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3370         };
3371
3372         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3373         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3374         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3375         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3376
3377         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3378         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3379         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3380         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3381
3382         hr = IDirect3DDevice9_EndScene(device);
3383         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3384     }
3385
3386     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3387     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3388     IDirect3DTexture9_Release(texture);
3389
3390     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3391     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3392     color = getPixelColor(device, 158, 118);
3393     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3394     color = getPixelColor(device, 162, 118);
3395     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3396     color = getPixelColor(device, 158, 122);
3397     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3398     color = getPixelColor(device, 162, 122);
3399     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3400
3401     color = getPixelColor(device, 158, 178);
3402     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3403     color = getPixelColor(device, 162, 178);
3404     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3405     color = getPixelColor(device, 158, 182);
3406     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3407     color = getPixelColor(device, 162, 182);
3408     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3409
3410     color = getPixelColor(device, 318, 118);
3411     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3412     color = getPixelColor(device, 322, 118);
3413     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3414     color = getPixelColor(device, 318, 122);
3415     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3416     color = getPixelColor(device, 322, 122);
3417     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3418
3419     color = getPixelColor(device, 318, 178);
3420     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3421     color = getPixelColor(device, 322, 178);
3422     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3423     color = getPixelColor(device, 318, 182);
3424     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3425     color = getPixelColor(device, 322, 182);
3426     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3427
3428     color = getPixelColor(device, 238, 298);
3429     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3430     color = getPixelColor(device, 242, 298);
3431     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3432     color = getPixelColor(device, 238, 302);
3433     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3434     color = getPixelColor(device, 242, 302);
3435     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3436
3437     color = getPixelColor(device, 238, 388);
3438     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3439     color = getPixelColor(device, 242, 388);
3440     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3441     color = getPixelColor(device, 238, 392);
3442     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3443     color = getPixelColor(device, 242, 392);
3444     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3445
3446     color = getPixelColor(device, 478, 298);
3447     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3448     color = getPixelColor(device, 482, 298);
3449     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3450     color = getPixelColor(device, 478, 302);
3451     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3452     color = getPixelColor(device, 482, 302);
3453     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3454
3455     color = getPixelColor(device, 478, 388);
3456     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3457     color = getPixelColor(device, 482, 388);
3458     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3459     color = getPixelColor(device, 478, 392);
3460     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3461     color = getPixelColor(device, 482, 392);
3462     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3463
3464     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3465     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3466     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3467      * Thus watch out if sampling from texels between 0 and 1.
3468      */
3469     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3470     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3471        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3472     if(!volume) {
3473         skip("Failed to create a volume texture\n");
3474         goto out;
3475     }
3476
3477     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3478     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3479     for(z = 0; z < 32; z++) {
3480         for(y = 0; y < 32; y++) {
3481             for(x = 0; x < 32; x++) {
3482                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3483                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3484                 float r_f = (float) x / 31.0;
3485                 float g_f = (float) y / 31.0;
3486                 float b_f = (float) z / 31.0;
3487
3488                 if(fmt == D3DFMT_A16B16G16R16) {
3489                     unsigned short *mem_s = mem;
3490                     mem_s[0]  = r_f * 65535.0;
3491                     mem_s[1]  = g_f * 65535.0;
3492                     mem_s[2]  = b_f * 65535.0;
3493                     mem_s[3]  = 65535;
3494                 } else {
3495                     unsigned char *mem_c = mem;
3496                     mem_c[0]  = b_f * 255.0;
3497                     mem_c[1]  = g_f * 255.0;
3498                     mem_c[2]  = r_f * 255.0;
3499                     mem_c[3]  = 255;
3500                 }
3501             }
3502         }
3503     }
3504     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3505     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3506
3507     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3508     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3509
3510     hr = IDirect3DDevice9_BeginScene(device);
3511     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3512     if(SUCCEEDED(hr))
3513     {
3514         float quad1[] = {
3515             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3516             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3517              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3518              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3519         };
3520         float quad2[] = {
3521             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3522             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3523              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3524              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3525         };
3526         float quad3[] = {
3527              0.0,       0.0,       0.1,     0.0,    0.0,
3528              0.0,       1.0,       0.1,     0.0,    0.0,
3529              1.0,       0.0,       0.1,     0.0,    0.0,
3530              1.0,       1.0,       0.1,     0.0,    0.0
3531         };
3532         float quad4[] = {
3533              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3534              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3535              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3536              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3537         };
3538         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3539                          0.0, 0.0, 1.0, 0.0,
3540                          0.0, 1.0, 0.0, 0.0,
3541                          0.0, 0.0, 0.0, 1.0};
3542         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3543         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3544
3545         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3546          * values
3547          */
3548         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3549         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3550         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3551         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3553         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3554
3555         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3556          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3557          * otherwise the w will be missing(blue).
3558          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3559          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3560          */
3561         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3562         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3564         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3565
3566         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3567         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3568         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3569         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3570         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3571         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3572         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3573         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3574         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3575
3576         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3577          * disable. ATI extends it up to the amount of values needed for the volume texture
3578          */
3579         memset(mat, 0, sizeof(mat));
3580         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3581         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3582         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3583         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3584         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3585         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3586         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3587         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3588
3589         hr = IDirect3DDevice9_EndScene(device);
3590         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3591     }
3592     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3593     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3594
3595     color = getPixelColor(device, 160, 360);
3596     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3597     color = getPixelColor(device, 160, 120);
3598     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3599        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3600     color = getPixelColor(device, 480, 120);
3601     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3602     color = getPixelColor(device, 480, 360);
3603     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3604
3605     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3606     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3607     hr = IDirect3DDevice9_BeginScene(device);
3608     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3609     if(SUCCEEDED(hr))
3610     {
3611         float quad1[] = {
3612             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3613             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3614              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3615              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3616         };
3617         float quad2[] = {
3618             -1.0,       0.0,       0.1,
3619             -1.0,       1.0,       0.1,
3620              0.0,       0.0,       0.1,
3621              0.0,       1.0,       0.1,
3622         };
3623         float quad3[] = {
3624              0.0,       0.0,       0.1,     1.0,
3625              0.0,       1.0,       0.1,     1.0,
3626              1.0,       0.0,       0.1,     1.0,
3627              1.0,       1.0,       0.1,     1.0
3628         };
3629         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3630                            0.0, 0.0, 0.0, 0.0,
3631                            0.0, 0.0, 0.0, 0.0,
3632                            0.0, 1.0, 0.0, 0.0};
3633         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3634                            1.0, 0.0, 0.0, 0.0,
3635                            0.0, 1.0, 0.0, 0.0,
3636                            0.0, 0.0, 1.0, 0.0};
3637         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3638         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3639
3640         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3641          */
3642         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3643         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3644         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3645         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3646         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3647         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3648
3649         /* None passed */
3650         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3651         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3652         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3653         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3654         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3655         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3656
3657         /* 4 used, 1 passed */
3658         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3659         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3660         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3661         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3662         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3663         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3664
3665         hr = IDirect3DDevice9_EndScene(device);
3666         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3667     }
3668     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3669     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3670     color = getPixelColor(device, 160, 360);
3671     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3672     color = getPixelColor(device, 160, 120);
3673     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3674     color = getPixelColor(device, 480, 120);
3675     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3676     /* Quad4: unused */
3677
3678     IDirect3DVolumeTexture9_Release(volume);
3679
3680     out:
3681     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3682     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3683     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3684     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3685     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3686     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3687     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3688     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3689     IDirect3DVertexDeclaration9_Release(decl);
3690     IDirect3DVertexDeclaration9_Release(decl2);
3691     IDirect3DVertexDeclaration9_Release(decl3);
3692 }
3693
3694 static void texdepth_test(IDirect3DDevice9 *device)
3695 {
3696     IDirect3DPixelShader9 *shader;
3697     HRESULT hr;
3698     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3699     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3700     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3701     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3702     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3703     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3704     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3705     DWORD shader_code[] = {
3706         0xffff0104,                                                                 /* ps_1_4               */
3707         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3708         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3709         0x0000fffd,                                                                 /* phase                */
3710         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3711         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3712         0x0000ffff                                                                  /* end                  */
3713     };
3714     DWORD color;
3715     float vertex[] = {
3716        -1.0,   -1.0,    0.0,
3717         1.0,   -1.0,    1.0,
3718        -1.0,    1.0,    0.0,
3719         1.0,    1.0,    1.0
3720     };
3721
3722     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3723     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3724
3725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3726     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3727     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3729     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3730     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3731     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3733     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3734
3735     /* Fill the depth buffer with a gradient */
3736     hr = IDirect3DDevice9_BeginScene(device);
3737     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3738     if(SUCCEEDED(hr))
3739     {
3740         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3741         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3742         hr = IDirect3DDevice9_EndScene(device);
3743         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3744     }
3745
3746     /* Now perform the actual tests. Same geometry, but with the shader */
3747     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3748     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3749     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3750     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3751     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3752     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3753
3754     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3755     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3756     hr = IDirect3DDevice9_BeginScene(device);
3757     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3758     if(SUCCEEDED(hr))
3759     {
3760         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3761         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3762
3763         hr = IDirect3DDevice9_EndScene(device);
3764         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3765     }
3766
3767     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3768     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3769     color = getPixelColor(device, 158, 240);
3770     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3771     color = getPixelColor(device, 162, 240);
3772     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3773
3774     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3775
3776     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3777     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3778     hr = IDirect3DDevice9_BeginScene(device);
3779     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3780     if(SUCCEEDED(hr))
3781     {
3782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3783         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3784
3785         hr = IDirect3DDevice9_EndScene(device);
3786         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3787     }
3788
3789     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3790     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3791     color = getPixelColor(device, 318, 240);
3792     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3793     color = getPixelColor(device, 322, 240);
3794     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3795
3796     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3797
3798     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3799     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3800     hr = IDirect3DDevice9_BeginScene(device);
3801     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3802     if(SUCCEEDED(hr))
3803     {
3804         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3805         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3806
3807         hr = IDirect3DDevice9_EndScene(device);
3808         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3809     }
3810     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3811     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3812
3813     color = getPixelColor(device, 1, 240);
3814     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3815
3816     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3817
3818     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3819     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3820     hr = IDirect3DDevice9_BeginScene(device);
3821     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3822     if(SUCCEEDED(hr))
3823     {
3824         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3825         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3826
3827         hr = IDirect3DDevice9_EndScene(device);
3828         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3829     }
3830     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3831     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3832     color = getPixelColor(device, 318, 240);
3833     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3834     color = getPixelColor(device, 322, 240);
3835     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3836
3837     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3838
3839     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3840     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3841     hr = IDirect3DDevice9_BeginScene(device);
3842     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3843     if(SUCCEEDED(hr))
3844     {
3845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3846         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3847
3848         hr = IDirect3DDevice9_EndScene(device);
3849         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3850     }
3851     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3852     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3853
3854     color = getPixelColor(device, 1, 240);
3855     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3856
3857     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3858
3859     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3860     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3861     hr = IDirect3DDevice9_BeginScene(device);
3862     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3863     if(SUCCEEDED(hr))
3864     {
3865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3866         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3867
3868         hr = IDirect3DDevice9_EndScene(device);
3869         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3870     }
3871     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3872     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3873
3874     color = getPixelColor(device, 638, 240);
3875     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3876
3877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3878
3879     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3880     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3881     hr = IDirect3DDevice9_BeginScene(device);
3882     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3883     if(SUCCEEDED(hr))
3884     {
3885         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3886         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3887
3888         hr = IDirect3DDevice9_EndScene(device);
3889         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3890     }
3891     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3892     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3893
3894     color = getPixelColor(device, 638, 240);
3895     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3896
3897     /* Cleanup */
3898     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3899     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3900     IDirect3DPixelShader9_Release(shader);
3901
3902     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3903     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3904     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3905     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3906 }
3907
3908 static void texkill_test(IDirect3DDevice9 *device)
3909 {
3910     IDirect3DPixelShader9 *shader;
3911     HRESULT hr;
3912     DWORD color;
3913
3914     const float vertex[] = {
3915     /*                          bottom  top    right    left */
3916         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3917          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3918         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3919          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3920     };
3921
3922     DWORD shader_code_11[] = {
3923     0xffff0101,                                                             /* ps_1_1                     */
3924     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3925     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3926     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3927     0x0000ffff                                                              /* end                        */
3928     };
3929     DWORD shader_code_20[] = {
3930     0xffff0200,                                                             /* ps_2_0                     */
3931     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3932     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3933     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3934     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3935     0x0000ffff                                                              /* end                        */
3936     };
3937
3938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3939     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3940     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3941     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3942
3943     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3944     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3945     hr = IDirect3DDevice9_BeginScene(device);
3946     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3947     if(SUCCEEDED(hr))
3948     {
3949         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3950         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3951         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3952         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3953         hr = IDirect3DDevice9_EndScene(device);
3954         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3955     }
3956     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3957     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3958     color = getPixelColor(device, 63, 46);
3959     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3960     color = getPixelColor(device, 66, 46);
3961     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3962     color = getPixelColor(device, 63, 49);
3963     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3964     color = getPixelColor(device, 66, 49);
3965     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3966
3967     color = getPixelColor(device, 578, 46);
3968     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3969     color = getPixelColor(device, 575, 46);
3970     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3971     color = getPixelColor(device, 578, 49);
3972     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3973     color = getPixelColor(device, 575, 49);
3974     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3975
3976     color = getPixelColor(device, 63, 430);
3977     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3978     color = getPixelColor(device, 63, 433);
3979     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3980     color = getPixelColor(device, 66, 433);
3981     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3982     color = getPixelColor(device, 66, 430);
3983     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3984
3985     color = getPixelColor(device, 578, 430);
3986     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3987     color = getPixelColor(device, 578, 433);
3988     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3989     color = getPixelColor(device, 575, 433);
3990     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3991     color = getPixelColor(device, 575, 430);
3992     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3993
3994     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3995     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3996     IDirect3DPixelShader9_Release(shader);
3997
3998     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3999     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4000     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4001     if(FAILED(hr)) {
4002         skip("Failed to create 2.0 test shader, most likely not supported\n");
4003         return;
4004     }
4005
4006     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4007     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4008     hr = IDirect3DDevice9_BeginScene(device);
4009     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4010     if(SUCCEEDED(hr))
4011     {
4012         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4013         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4014         hr = IDirect3DDevice9_EndScene(device);
4015         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4016     }
4017     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4018
4019     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4020     color = getPixelColor(device, 63, 46);
4021     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4022     color = getPixelColor(device, 66, 46);
4023     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4024     color = getPixelColor(device, 63, 49);
4025     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4026     color = getPixelColor(device, 66, 49);
4027     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4028
4029     color = getPixelColor(device, 578, 46);
4030     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4031     color = getPixelColor(device, 575, 46);
4032     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4033     color = getPixelColor(device, 578, 49);
4034     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4035     color = getPixelColor(device, 575, 49);
4036     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4037
4038     color = getPixelColor(device, 63, 430);
4039     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4040     color = getPixelColor(device, 63, 433);
4041     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4042     color = getPixelColor(device, 66, 433);
4043     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4044     color = getPixelColor(device, 66, 430);
4045     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4046
4047     color = getPixelColor(device, 578, 430);
4048     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4049     color = getPixelColor(device, 578, 433);
4050     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4051     color = getPixelColor(device, 575, 433);
4052     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4053     color = getPixelColor(device, 575, 430);
4054     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4055
4056     /* Cleanup */
4057     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4058     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4059     IDirect3DPixelShader9_Release(shader);
4060 }
4061
4062 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4063 {
4064     IDirect3D9 *d3d9;
4065     HRESULT hr;
4066     IDirect3DTexture9 *texture;
4067     IDirect3DPixelShader9 *shader;
4068     IDirect3DPixelShader9 *shader2;
4069     D3DLOCKED_RECT lr;
4070     DWORD color;
4071     DWORD shader_code[] = {
4072         0xffff0101,                             /* ps_1_1       */
4073         0x00000042, 0xb00f0000,                 /* tex t0       */
4074         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4075         0x0000ffff                              /* end          */
4076     };
4077     DWORD shader_code2[] = {
4078         0xffff0101,                             /* ps_1_1       */
4079         0x00000042, 0xb00f0000,                 /* tex t0       */
4080         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4081         0x0000ffff                              /* end          */
4082     };
4083
4084     float quad[] = {
4085        -1.0,   -1.0,   0.1,     0.5,    0.5,
4086         1.0,   -1.0,   0.1,     0.5,    0.5,
4087        -1.0,    1.0,   0.1,     0.5,    0.5,
4088         1.0,    1.0,   0.1,     0.5,    0.5,
4089     };
4090
4091     memset(&lr, 0, sizeof(lr));
4092     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4093     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4094                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4095     IDirect3D9_Release(d3d9);
4096     if(FAILED(hr)) {
4097         skip("No D3DFMT_X8L8V8U8 support\n");
4098     };
4099
4100     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4101     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4102
4103     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4105     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4106     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4107     *((DWORD *) lr.pBits) = 0x11ca3141;
4108     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4109     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4110
4111     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4112     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4113     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4114     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4115
4116     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4117     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4118     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4119     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4120     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4121     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4122
4123     hr = IDirect3DDevice9_BeginScene(device);
4124     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4125     if(SUCCEEDED(hr))
4126     {
4127         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4128         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4129
4130         hr = IDirect3DDevice9_EndScene(device);
4131         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4132     }
4133     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4134     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4135     color = getPixelColor(device, 578, 430);
4136     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4137        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4138
4139     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4140     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4141     hr = IDirect3DDevice9_BeginScene(device);
4142     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4143     if(SUCCEEDED(hr))
4144     {
4145         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4146         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4147
4148         hr = IDirect3DDevice9_EndScene(device);
4149         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4150     }
4151     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4153     color = getPixelColor(device, 578, 430);
4154     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4155
4156     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4157     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4158     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4159     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4160     IDirect3DPixelShader9_Release(shader);
4161     IDirect3DPixelShader9_Release(shader2);
4162     IDirect3DTexture9_Release(texture);
4163 }
4164
4165 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4166 {
4167     HRESULT hr;
4168     IDirect3D9 *d3d;
4169     IDirect3DTexture9 *texture = NULL;
4170     IDirect3DSurface9 *surface;
4171     DWORD color;
4172     const RECT r1 = {256, 256, 512, 512};
4173     const RECT r2 = {512, 256, 768, 512};
4174     const RECT r3 = {256, 512, 512, 768};
4175     const RECT r4 = {512, 512, 768, 768};
4176     unsigned int x, y;
4177     D3DLOCKED_RECT lr;
4178     memset(&lr, 0, sizeof(lr));
4179
4180     IDirect3DDevice9_GetDirect3D(device, &d3d);
4181     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4182        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4183         skip("No autogenmipmap support\n");
4184         IDirect3D9_Release(d3d);
4185         return;
4186     }
4187     IDirect3D9_Release(d3d);
4188
4189     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4190     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4191
4192     /* Make the mipmap big, so that a smaller mipmap is used
4193      */
4194     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4195                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4196     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4197
4198     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4199     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4200     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4201     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4202     for(y = 0; y < 1024; y++) {
4203         for(x = 0; x < 1024; x++) {
4204             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4205             POINT pt;
4206
4207             pt.x = x;
4208             pt.y = y;
4209             if(PtInRect(&r1, pt)) {
4210                 *dst = 0xffff0000;
4211             } else if(PtInRect(&r2, pt)) {
4212                 *dst = 0xff00ff00;
4213             } else if(PtInRect(&r3, pt)) {
4214                 *dst = 0xff0000ff;
4215             } else if(PtInRect(&r4, pt)) {
4216                 *dst = 0xff000000;
4217             } else {
4218                 *dst = 0xffffffff;
4219             }
4220         }
4221     }
4222     hr = IDirect3DSurface9_UnlockRect(surface);
4223     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4224     IDirect3DSurface9_Release(surface);
4225
4226     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4227     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4228     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4229     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4230
4231     hr = IDirect3DDevice9_BeginScene(device);
4232     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4233     if(SUCCEEDED(hr)) {
4234         const float quad[] =  {
4235            -0.5,   -0.5,    0.1,    0.0,    0.0,
4236            -0.5,    0.5,    0.1,    0.0,    1.0,
4237             0.5,   -0.5,    0.1,    1.0,    0.0,
4238             0.5,    0.5,    0.1,    1.0,    1.0
4239         };
4240
4241         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4242         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4243         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4244         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4245         hr = IDirect3DDevice9_EndScene(device);
4246         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4247     }
4248     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4249     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4250     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4251     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4252     IDirect3DTexture9_Release(texture);
4253
4254     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4255     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4256     color = getPixelColor(device, 200, 200);
4257     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4258     color = getPixelColor(device, 280, 200);
4259     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4260     color = getPixelColor(device, 360, 200);
4261     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4262     color = getPixelColor(device, 440, 200);
4263     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4264     color = getPixelColor(device, 200, 270);
4265     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4266     color = getPixelColor(device, 280, 270);
4267     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4268     color = getPixelColor(device, 360, 270);
4269     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4270     color = getPixelColor(device, 440, 270);
4271     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4272 }
4273
4274 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4275 {
4276     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4277     IDirect3DVertexDeclaration9 *decl;
4278     HRESULT hr;
4279     DWORD color;
4280     DWORD shader_code_11[] =  {
4281         0xfffe0101,                                         /* vs_1_1           */
4282         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4283         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4284         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4285         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4286         0x0000ffff                                          /* end              */
4287     };
4288     DWORD shader_code_11_2[] =  {
4289         0xfffe0101,                                         /* vs_1_1           */
4290         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4291         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4292         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4293         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4294         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4295         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4296         0x0000ffff                                          /* end              */
4297     };
4298     DWORD shader_code_20[] =  {
4299         0xfffe0200,                                         /* vs_2_0           */
4300         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4301         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4302         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4303         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4304         0x0000ffff                                          /* end              */
4305     };
4306     DWORD shader_code_20_2[] =  {
4307         0xfffe0200,                                         /* vs_2_0           */
4308         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4309         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4310         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4311         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4312         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4313         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4314         0x0000ffff                                          /* end              */
4315     };
4316     static const D3DVERTEXELEMENT9 decl_elements[] = {
4317         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4318         D3DDECL_END()
4319     };
4320     float quad1[] = {
4321         -1.0,   -1.0,   0.1,
4322          0.0,   -1.0,   0.1,
4323         -1.0,    0.0,   0.1,
4324          0.0,    0.0,   0.1
4325     };
4326     float quad2[] = {
4327          0.0,   -1.0,   0.1,
4328          1.0,   -1.0,   0.1,
4329          0.0,    0.0,   0.1,
4330          1.0,    0.0,   0.1
4331     };
4332     float quad3[] = {
4333          0.0,    0.0,   0.1,
4334          1.0,    0.0,   0.1,
4335          0.0,    1.0,   0.1,
4336          1.0,    1.0,   0.1
4337     };
4338     float quad4[] = {
4339         -1.0,    0.0,   0.1,
4340          0.0,    0.0,   0.1,
4341         -1.0,    1.0,   0.1,
4342          0.0,    1.0,   0.1
4343     };
4344     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4345     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4346
4347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4348     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4349
4350     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4351     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4352     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4353     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4354     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4355     if(FAILED(hr)) shader_20 = NULL;
4356     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4357     if(FAILED(hr)) shader_20_2 = NULL;
4358     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4359     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4360
4361     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4362     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4363     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4364     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4365     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4366     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4367
4368     hr = IDirect3DDevice9_BeginScene(device);
4369     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4370     if(SUCCEEDED(hr))
4371     {
4372         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4373         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4374         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4375         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4376
4377         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4378         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4379         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4380         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4381
4382         if(shader_20) {
4383             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4384             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4385             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4386             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4387         }
4388
4389         if(shader_20_2) {
4390             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4391             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4392             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4393             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4394         }
4395
4396         hr = IDirect3DDevice9_EndScene(device);
4397         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4398     }
4399     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4400     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4401
4402     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4403     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4404     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4405     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4406
4407     color = getPixelColor(device, 160, 360);
4408     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4409        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4410     color = getPixelColor(device, 480, 360);
4411     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4412        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4413     if(shader_20) {
4414         color = getPixelColor(device, 160, 120);
4415         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4416            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4417     }
4418     if(shader_20_2) {
4419         color = getPixelColor(device, 480, 120);
4420         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4421            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4422     }
4423
4424     IDirect3DVertexDeclaration9_Release(decl);
4425     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4426     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4427     IDirect3DVertexShader9_Release(shader_11_2);
4428     IDirect3DVertexShader9_Release(shader_11);
4429 }
4430
4431 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4432 {
4433     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4434     HRESULT hr;
4435     DWORD color;
4436     DWORD shader_code_11[] =  {
4437         0xffff0101,                                         /* ps_1_1           */
4438         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4439         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4440         0x0000ffff                                          /* end              */
4441     };
4442     DWORD shader_code_12[] =  {
4443         0xffff0102,                                         /* ps_1_2           */
4444         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4445         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4446         0x0000ffff                                          /* end              */
4447     };
4448     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4449      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4450      * During development of this test, 1.3 shaders were verified too
4451      */
4452     DWORD shader_code_14[] =  {
4453         0xffff0104,                                         /* ps_1_4           */
4454         /* Try to make one constant local. It gets clamped too, although the binary contains
4455          * the bigger numbers
4456          */
4457         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4458         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4459         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4460         0x0000ffff                                          /* end              */
4461     };
4462     DWORD shader_code_20[] =  {
4463         0xffff0200,                                         /* ps_2_0           */
4464         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4465         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4466         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4467         0x0000ffff                                          /* end              */
4468     };
4469     float quad1[] = {
4470         -1.0,   -1.0,   0.1,
4471          0.0,   -1.0,   0.1,
4472         -1.0,    0.0,   0.1,
4473          0.0,    0.0,   0.1
4474     };
4475     float quad2[] = {
4476          0.0,   -1.0,   0.1,
4477          1.0,   -1.0,   0.1,
4478          0.0,    0.0,   0.1,
4479          1.0,    0.0,   0.1
4480     };
4481     float quad3[] = {
4482          0.0,    0.0,   0.1,
4483          1.0,    0.0,   0.1,
4484          0.0,    1.0,   0.1,
4485          1.0,    1.0,   0.1
4486     };
4487     float quad4[] = {
4488         -1.0,    0.0,   0.1,
4489          0.0,    0.0,   0.1,
4490         -1.0,    1.0,   0.1,
4491          0.0,    1.0,   0.1
4492     };
4493     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4494     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4495
4496     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4497     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4498
4499     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4500     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4501     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4502     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4503     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4504     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4505     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4506     if(FAILED(hr)) shader_20 = NULL;
4507
4508     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4509     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4510     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4511     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4512     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4513     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4514
4515     hr = IDirect3DDevice9_BeginScene(device);
4516     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4517     if(SUCCEEDED(hr))
4518     {
4519         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4520         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4521         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4522         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4523
4524         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4525         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4526         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4527         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4528
4529         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4530         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4531         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4532         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4533
4534         if(shader_20) {
4535             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4536             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4537             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4538             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4539         }
4540
4541         hr = IDirect3DDevice9_EndScene(device);
4542         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4543     }
4544     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4545     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4546
4547     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4548     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4549
4550     color = getPixelColor(device, 160, 360);
4551     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4552        "quad 1 has color %08x, expected 0x00808000\n", color);
4553     color = getPixelColor(device, 480, 360);
4554     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4555        "quad 2 has color %08x, expected 0x00808000\n", color);
4556     color = getPixelColor(device, 480, 120);
4557     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4558        "quad 3 has color %08x, expected 0x00808000\n", color);
4559     if(shader_20) {
4560         color = getPixelColor(device, 160, 120);
4561         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4562            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4563     }
4564
4565     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4566     IDirect3DPixelShader9_Release(shader_14);
4567     IDirect3DPixelShader9_Release(shader_12);
4568     IDirect3DPixelShader9_Release(shader_11);
4569 }
4570
4571 static void dp2add_ps_test(IDirect3DDevice9 *device)
4572 {
4573     IDirect3DPixelShader9 *shader_dp2add = NULL;
4574     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4575     HRESULT hr;
4576     DWORD color;
4577
4578     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4579      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4580      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4581      * r0 first.
4582      * The result here for the r,g,b components should be roughly 0.5:
4583      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4584     static const DWORD shader_code_dp2add[] =  {
4585         0xffff0200,                                                             /* ps_2_0                       */
4586         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4587
4588         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4589         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4590
4591         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4592         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4593         0x0000ffff                                                              /* end                          */
4594     };
4595
4596     /* Test the _sat modifier, too.  Result here should be:
4597      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4598      *      _SAT: ==> 1.0
4599      *   ADD: (1.0 + -0.5) = 0.5
4600      */
4601     static const DWORD shader_code_dp2add_sat[] =  {
4602         0xffff0200,                                                             /* ps_2_0                           */
4603         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4604
4605         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4606         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4607         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4608
4609         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4610         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4611         0x0000ffff                                                              /* end                              */
4612     };
4613
4614     const float quad[] = {
4615         -1.0,   -1.0,   0.1,
4616          1.0,   -1.0,   0.1,
4617         -1.0,    1.0,   0.1,
4618          1.0,    1.0,   0.1
4619     };
4620
4621
4622     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4623     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4624
4625     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4626     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4627
4628     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4629     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4630
4631     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4632     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4633
4634     if (shader_dp2add) {
4635
4636         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4637         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4638
4639         hr = IDirect3DDevice9_BeginScene(device);
4640         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4641         if(SUCCEEDED(hr))
4642         {
4643             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4644             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4645
4646             hr = IDirect3DDevice9_EndScene(device);
4647             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4648         }
4649         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4650         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4651
4652         color = getPixelColor(device, 360, 240);
4653         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4654
4655         IDirect3DPixelShader9_Release(shader_dp2add);
4656     } else {
4657         skip("dp2add shader creation failed\n");
4658     }
4659
4660     if (shader_dp2add_sat) {
4661
4662         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4663         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4664
4665         hr = IDirect3DDevice9_BeginScene(device);
4666         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4667         if(SUCCEEDED(hr))
4668         {
4669             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4670             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4671
4672             hr = IDirect3DDevice9_EndScene(device);
4673             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4674         }
4675         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4676         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4677
4678         color = getPixelColor(device, 360, 240);
4679         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4680
4681         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4682     } else {
4683         skip("dp2add shader creation failed\n");
4684     }
4685
4686     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4687     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4688 }
4689
4690 static void cnd_test(IDirect3DDevice9 *device)
4691 {
4692     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4693     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4694     HRESULT hr;
4695     DWORD color;
4696     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4697      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4698      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4699      */
4700     DWORD shader_code_11[] =  {
4701         0xffff0101,                                                                 /* ps_1_1               */
4702         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4703         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4704         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4705         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4706         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4707         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4708         0x0000ffff                                                                  /* end                  */
4709     };
4710     DWORD shader_code_12[] =  {
4711         0xffff0102,                                                                 /* ps_1_2               */
4712         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4713         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4714         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4715         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4716         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4717         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4718         0x0000ffff                                                                  /* end                  */
4719     };
4720     DWORD shader_code_13[] =  {
4721         0xffff0103,                                                                 /* ps_1_3               */
4722         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4723         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4724         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4725         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4726         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4727         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4728         0x0000ffff                                                                  /* end                  */
4729     };
4730     DWORD shader_code_14[] =  {
4731         0xffff0104,                                                                 /* ps_1_3               */
4732         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4733         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4734         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4735         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4736         0x0000ffff                                                                  /* end                  */
4737     };
4738
4739     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4740      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4741      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4742      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4743      * native CreatePixelShader returns an error.
4744      *
4745      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4746      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4747      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4748      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4749      */
4750     DWORD shader_code_11_coissue[] =  {
4751         0xffff0101,                                                             /* ps_1_1                   */
4752         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4753         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4754         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4755         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4756         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4757         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4758         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4759         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4760         /* 0x40000000 = D3DSI_COISSUE */
4761         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4762         0x0000ffff                                                              /* end                      */
4763     };
4764     DWORD shader_code_12_coissue[] =  {
4765         0xffff0102,                                                             /* ps_1_2                   */
4766         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4767         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4768         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4769         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4770         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4771         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4772         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4773         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4774         /* 0x40000000 = D3DSI_COISSUE */
4775         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4776         0x0000ffff                                                              /* end                      */
4777     };
4778     DWORD shader_code_13_coissue[] =  {
4779         0xffff0103,                                                             /* ps_1_3                   */
4780         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4781         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4782         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4783         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4784         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4785         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4786         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4787         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4788         /* 0x40000000 = D3DSI_COISSUE */
4789         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4790         0x0000ffff                                                              /* end                      */
4791     };
4792     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4793      * compare against 0.5
4794      */
4795     DWORD shader_code_14_coissue[] =  {
4796         0xffff0104,                                                             /* ps_1_4                   */
4797         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4798         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4799         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4800         /* 0x40000000 = D3DSI_COISSUE */
4801         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4802         0x0000ffff                                                              /* end                      */
4803     };
4804     float quad1[] = {
4805         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4806          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4807         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4808          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4809     };
4810     float quad2[] = {
4811          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4812          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4813          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4814          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4815     };
4816     float quad3[] = {
4817          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4818          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4819          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4820          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4821     };
4822     float quad4[] = {
4823         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4824          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4825         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4826          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4827     };
4828     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4829     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4830     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4831     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4832
4833     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4834     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4835
4836     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4837     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4838     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4839     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4840     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4841     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4842     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4843     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4844     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4845     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4846     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4847     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4848     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4849     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4850     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4851     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4852
4853     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4854     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4855     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4856     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4857     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4858     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4859
4860     hr = IDirect3DDevice9_BeginScene(device);
4861     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4862     if(SUCCEEDED(hr))
4863     {
4864         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4865         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4866         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4867         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4868
4869         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4870         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4872         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4873
4874         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4875         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4876         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4877         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4878
4879         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4880         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4881         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4882         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4883
4884         hr = IDirect3DDevice9_EndScene(device);
4885         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4886     }
4887     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4888     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4889
4890     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4891     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4892
4893     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4894     color = getPixelColor(device, 158, 118);
4895     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4896     color = getPixelColor(device, 162, 118);
4897     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4898     color = getPixelColor(device, 158, 122);
4899     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4900     color = getPixelColor(device, 162, 122);
4901     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4902
4903     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4904     color = getPixelColor(device, 158, 358);
4905     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4906     color = getPixelColor(device, 162, 358);
4907     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4908         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4909     color = getPixelColor(device, 158, 362);
4910     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4911     color = getPixelColor(device, 162, 362);
4912     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4913         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4914
4915     /* 1.2 shader */
4916     color = getPixelColor(device, 478, 358);
4917     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4918     color = getPixelColor(device, 482, 358);
4919     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4920         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4921     color = getPixelColor(device, 478, 362);
4922     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4923     color = getPixelColor(device, 482, 362);
4924     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4925         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4926
4927     /* 1.3 shader */
4928     color = getPixelColor(device, 478, 118);
4929     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4930     color = getPixelColor(device, 482, 118);
4931     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4932         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4933     color = getPixelColor(device, 478, 122);
4934     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4935     color = getPixelColor(device, 482, 122);
4936     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4937         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4938
4939     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4940     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4941     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4942     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4943     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4944     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4945
4946     hr = IDirect3DDevice9_BeginScene(device);
4947     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4948     if(SUCCEEDED(hr))
4949     {
4950         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4951         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4953         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4954
4955         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4956         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4957         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4958         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4959
4960         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4961         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4962         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4963         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4964
4965         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4966         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4967         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4968         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4969
4970         hr = IDirect3DDevice9_EndScene(device);
4971         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4972     }
4973     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4974     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4975
4976     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4977     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4978
4979     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4980      * that we swapped the values in c1 and c2 to make the other tests return some color
4981      */
4982     color = getPixelColor(device, 158, 118);
4983     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4984     color = getPixelColor(device, 162, 118);
4985     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4986     color = getPixelColor(device, 158, 122);
4987     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4988     color = getPixelColor(device, 162, 122);
4989     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4990
4991     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4992     color = getPixelColor(device, 158, 358);
4993     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4994         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4995     color = getPixelColor(device, 162, 358);
4996     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4997         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4998     color = getPixelColor(device, 158, 362);
4999     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5000         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5001     color = getPixelColor(device, 162, 362);
5002     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5003         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5004
5005     /* 1.2 shader */
5006     color = getPixelColor(device, 478, 358);
5007     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5008         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5009     color = getPixelColor(device, 482, 358);
5010     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5011         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5012     color = getPixelColor(device, 478, 362);
5013     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5014         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5015     color = getPixelColor(device, 482, 362);
5016     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5017         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5018
5019     /* 1.3 shader */
5020     color = getPixelColor(device, 478, 118);
5021     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5022         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5023     color = getPixelColor(device, 482, 118);
5024     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5025         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5026     color = getPixelColor(device, 478, 122);
5027     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5028         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5029     color = getPixelColor(device, 482, 122);
5030     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5031         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5032
5033     IDirect3DPixelShader9_Release(shader_14_coissue);
5034     IDirect3DPixelShader9_Release(shader_13_coissue);
5035     IDirect3DPixelShader9_Release(shader_12_coissue);
5036     IDirect3DPixelShader9_Release(shader_11_coissue);
5037     IDirect3DPixelShader9_Release(shader_14);
5038     IDirect3DPixelShader9_Release(shader_13);
5039     IDirect3DPixelShader9_Release(shader_12);
5040     IDirect3DPixelShader9_Release(shader_11);
5041 }
5042
5043 static void nested_loop_test(IDirect3DDevice9 *device) {
5044     const DWORD shader_code[] = {
5045         0xffff0300,                                                             /* ps_3_0               */
5046         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5047         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5048         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5049         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5050         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5051         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5052         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5053         0x0000001d,                                                             /* endloop              */
5054         0x0000001d,                                                             /* endloop              */
5055         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5056         0x0000ffff                                                              /* end                  */
5057     };
5058     IDirect3DPixelShader9 *shader;
5059     HRESULT hr;
5060     DWORD color;
5061     const float quad[] = {
5062         -1.0,   -1.0,   0.1,
5063          1.0,   -1.0,   0.1,
5064         -1.0,    1.0,   0.1,
5065          1.0,    1.0,   0.1
5066     };
5067
5068     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5069     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5070     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5071     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5072     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5073     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5074     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5075     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5076
5077     hr = IDirect3DDevice9_BeginScene(device);
5078     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5079     if(SUCCEEDED(hr))
5080     {
5081         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5082         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5083         hr = IDirect3DDevice9_EndScene(device);
5084         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5085     }
5086     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5087     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5088
5089     color = getPixelColor(device, 360, 240);
5090     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5091        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5092
5093     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5094     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5095     IDirect3DPixelShader9_Release(shader);
5096 }
5097
5098 struct varying_test_struct
5099 {
5100     const DWORD             *shader_code;
5101     IDirect3DPixelShader9   *shader;
5102     DWORD                   color, color_rhw;
5103     const char              *name;
5104     BOOL                    todo, todo_rhw;
5105 };
5106
5107 struct hugeVertex
5108 {
5109     float pos_x,        pos_y,      pos_z,      rhw;
5110     float weight_1,     weight_2,   weight_3,   weight_4;
5111     float index_1,      index_2,    index_3,    index_4;
5112     float normal_1,     normal_2,   normal_3,   normal_4;
5113     float fog_1,        fog_2,      fog_3,      fog_4;
5114     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5115     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5116     float binormal_1,   binormal_2, binormal_3, binormal_4;
5117     float depth_1,      depth_2,    depth_3,    depth_4;
5118     DWORD diffuse, specular;
5119 };
5120
5121 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5122     /* dcl_position: fails to compile */
5123     const DWORD blendweight_code[] = {
5124         0xffff0300,                             /* ps_3_0                   */
5125         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5126         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5127         0x0000ffff                              /* end                      */
5128     };
5129     const DWORD blendindices_code[] = {
5130         0xffff0300,                             /* ps_3_0                   */
5131         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5132         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5133         0x0000ffff                              /* end                      */
5134     };
5135     const DWORD normal_code[] = {
5136         0xffff0300,                             /* ps_3_0                   */
5137         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5138         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5139         0x0000ffff                              /* end                      */
5140     };
5141     /* psize: fails? */
5142     const DWORD texcoord0_code[] = {
5143         0xffff0300,                             /* ps_3_0                   */
5144         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5145         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5146         0x0000ffff                              /* end                      */
5147     };
5148     const DWORD tangent_code[] = {
5149         0xffff0300,                             /* ps_3_0                   */
5150         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5151         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5152         0x0000ffff                              /* end                      */
5153     };
5154     const DWORD binormal_code[] = {
5155         0xffff0300,                             /* ps_3_0                   */
5156         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5157         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5158         0x0000ffff                              /* end                      */
5159     };
5160     /* tessfactor: fails */
5161     /* positiont: fails */
5162     const DWORD color_code[] = {
5163         0xffff0300,                             /* ps_3_0                   */
5164         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5165         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5166         0x0000ffff                              /* end                      */
5167     };
5168     const DWORD fog_code[] = {
5169         0xffff0300,                             /* ps_3_0                   */
5170         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5171         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5172         0x0000ffff                              /* end                      */
5173     };
5174     const DWORD depth_code[] = {
5175         0xffff0300,                             /* ps_3_0                   */
5176         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5177         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5178         0x0000ffff                              /* end                      */
5179     };
5180     const DWORD specular_code[] = {
5181         0xffff0300,                             /* ps_3_0                   */
5182         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5183         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5184         0x0000ffff                              /* end                      */
5185     };
5186     /* sample: fails */
5187
5188     struct varying_test_struct tests[] = {
5189        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5190        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5191        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5192        /* Why does dx not forward the texcoord? */
5193        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5194        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5195        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5196        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5197        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5198        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5199        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5200     };
5201     /* Declare a monster vertex type :-) */
5202     static const D3DVERTEXELEMENT9 decl_elements[] = {
5203         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5204         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5205         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5206         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5207         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5208         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5209         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5210         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5211         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5212         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5213         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5214         D3DDECL_END()
5215     };
5216     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5217         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5218         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5219         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5220         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5221         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5222         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5223         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5224         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5225         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5226         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5227         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5228         D3DDECL_END()
5229     };
5230     struct hugeVertex data[4] = {
5231         {
5232             -1.0,   -1.0,   0.1,    1.0,
5233              0.1,    0.1,   0.1,    0.1,
5234              0.2,    0.2,   0.2,    0.2,
5235              0.3,    0.3,   0.3,    0.3,
5236              0.4,    0.4,   0.4,    0.4,
5237              0.50,   0.55,  0.55,   0.55,
5238              0.6,    0.6,   0.6,    0.7,
5239              0.7,    0.7,   0.7,    0.6,
5240              0.8,    0.8,   0.8,    0.8,
5241              0xe6e6e6e6, /* 0.9 * 256 */
5242              0x224488ff  /* Nothing special */
5243         },
5244         {
5245              1.0,   -1.0,   0.1,    1.0,
5246              0.1,    0.1,   0.1,    0.1,
5247              0.2,    0.2,   0.2,    0.2,
5248              0.3,    0.3,   0.3,    0.3,
5249              0.4,    0.4,   0.4,    0.4,
5250              0.50,   0.55,  0.55,   0.55,
5251              0.6,    0.6,   0.6,    0.7,
5252              0.7,    0.7,   0.7,    0.6,
5253              0.8,    0.8,   0.8,    0.8,
5254              0xe6e6e6e6, /* 0.9 * 256 */
5255              0x224488ff /* Nothing special */
5256         },
5257         {
5258             -1.0,    1.0,   0.1,    1.0,
5259              0.1,    0.1,   0.1,    0.1,
5260              0.2,    0.2,   0.2,    0.2,
5261              0.3,    0.3,   0.3,    0.3,
5262              0.4,    0.4,   0.4,    0.4,
5263              0.50,   0.55,  0.55,   0.55,
5264              0.6,    0.6,   0.6,    0.7,
5265              0.7,    0.7,   0.7,    0.6,
5266              0.8,    0.8,   0.8,    0.8,
5267              0xe6e6e6e6, /* 0.9 * 256 */
5268              0x224488ff /* Nothing special */
5269         },
5270         {
5271              1.0,    1.0,   0.1,    1.0,
5272              0.1,    0.1,   0.1,    0.1,
5273              0.2,    0.2,   0.2,    0.2,
5274              0.3,    0.3,   0.3,    0.3,
5275              0.4,    0.4,   0.4,    0.4,
5276              0.50,   0.55,  0.55,   0.55,
5277              0.6,    0.6,   0.6,    0.7,
5278              0.7,    0.7,   0.7,    0.6,
5279              0.8,    0.8,   0.8,    0.8,
5280              0xe6e6e6e6, /* 0.9 * 256 */
5281              0x224488ff /* Nothing special */
5282         },
5283     };
5284     struct hugeVertex data2[4];
5285     IDirect3DVertexDeclaration9 *decl;
5286     IDirect3DVertexDeclaration9 *decl2;
5287     HRESULT hr;
5288     unsigned int i;
5289     DWORD color, r, g, b, r_e, g_e, b_e;
5290     BOOL drawok;
5291
5292     memcpy(data2, data, sizeof(data2));
5293     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5294     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5295     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5296     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5297
5298     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5299     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5300     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5302     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5303     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5304
5305     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5306     {
5307         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5308         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5309            tests[i].name, hr);
5310     }
5311
5312     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5313     {
5314         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5315         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5316
5317         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5318         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5319
5320         hr = IDirect3DDevice9_BeginScene(device);
5321         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5322         drawok = FALSE;
5323         if(SUCCEEDED(hr))
5324         {
5325             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5326             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5327             drawok = SUCCEEDED(hr);
5328             hr = IDirect3DDevice9_EndScene(device);
5329             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5330         }
5331         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5332         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5333
5334         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5335          * the failure and do not check the color if it failed
5336          */
5337         if(!drawok) {
5338             continue;
5339         }
5340
5341         color = getPixelColor(device, 360, 240);
5342         r = color & 0x00ff0000 >> 16;
5343         g = color & 0x0000ff00 >>  8;
5344         b = color & 0x000000ff;
5345         r_e = tests[i].color & 0x00ff0000 >> 16;
5346         g_e = tests[i].color & 0x0000ff00 >>  8;
5347         b_e = tests[i].color & 0x000000ff;
5348
5349         if(tests[i].todo) {
5350             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5351                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5352                          tests[i].name, color, tests[i].color);
5353         } else {
5354             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5355                "Test %s returned color 0x%08x, expected 0x%08x\n",
5356                tests[i].name, color, tests[i].color);
5357         }
5358     }
5359
5360     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5361     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5362     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5363     {
5364         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5365         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5366
5367         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5368         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5369
5370         hr = IDirect3DDevice9_BeginScene(device);
5371         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5372         if(SUCCEEDED(hr))
5373         {
5374             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5375             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5376             hr = IDirect3DDevice9_EndScene(device);
5377             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5378         }
5379         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5380         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5381
5382         color = getPixelColor(device, 360, 240);
5383         r = color & 0x00ff0000 >> 16;
5384         g = color & 0x0000ff00 >>  8;
5385         b = color & 0x000000ff;
5386         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5387         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5388         b_e = tests[i].color_rhw & 0x000000ff;
5389
5390         if(tests[i].todo_rhw) {
5391             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5392              * pipeline
5393              */
5394             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5395                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5396                          tests[i].name, color, tests[i].color_rhw);
5397         } else {
5398             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5399                "Test %s returned color 0x%08x, expected 0x%08x\n",
5400                tests[i].name, color, tests[i].color_rhw);
5401         }
5402     }
5403
5404     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5405     {
5406         IDirect3DPixelShader9_Release(tests[i].shader);
5407     }
5408
5409     IDirect3DVertexDeclaration9_Release(decl2);
5410     IDirect3DVertexDeclaration9_Release(decl);
5411 }
5412
5413 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5414     static const DWORD ps_code[] = {
5415     0xffff0300,                                                             /* ps_3_0                       */
5416     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5417     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5418     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5419     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5420     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5421     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5422     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5423     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5424     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5425
5426     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5427     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5428     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5429     0x0000001d,                                                             /* endloop                      */
5430     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5431     0x0000ffff                                                              /* end                          */
5432     };
5433     static const DWORD vs_1_code[] = {
5434     0xfffe0101,                                                             /* vs_1_1                       */
5435     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5436     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5437     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5438     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5439     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5440     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5441     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5442     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5443     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5444     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5445     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5446     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5447     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5448     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5449     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5450     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5451     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5452     0x0000ffff
5453     };
5454     DWORD vs_2_code[] = {
5455     0xfffe0200,                                                             /* vs_2_0                       */
5456     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5457     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5458     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5459     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5460     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5461     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5462     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5463     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5464     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5465     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5466     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5467     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5468     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5469     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5470     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5471     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5472     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5473     0x0000ffff                                                              /* end                          */
5474     };
5475     /* TODO: Define normal, tangent, blendweight and depth here */
5476     static const DWORD vs_3_code[] = {
5477     0xfffe0300,                                                             /* vs_3_0                       */
5478     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5479     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5480     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5481     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5482     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5483     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5484     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5485     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5486     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5487     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5488     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5489     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5490     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5491     0x0000ffff                                                              /* end                          */
5492     };
5493     float quad1[] =  {
5494         -1.0,   -1.0,   0.1,
5495          0.0,   -1.0,   0.1,
5496         -1.0,    0.0,   0.1,
5497          0.0,    0.0,   0.1
5498     };
5499     float quad2[] =  {
5500          0.0,   -1.0,   0.1,
5501          1.0,   -1.0,   0.1,
5502          0.0,    0.0,   0.1,
5503          1.0,    0.0,   0.1
5504     };
5505     float quad3[] =  {
5506         -1.0,    0.0,   0.1,
5507          0.0,    0.0,   0.1,
5508         -1.0,    1.0,   0.1,
5509          0.0,    1.0,   0.1
5510     };
5511
5512     HRESULT hr;
5513     DWORD color;
5514     IDirect3DPixelShader9 *pixelshader = NULL;
5515     IDirect3DVertexShader9 *vs_1_shader = NULL;
5516     IDirect3DVertexShader9 *vs_2_shader = NULL;
5517     IDirect3DVertexShader9 *vs_3_shader = NULL;
5518
5519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5520
5521     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5522     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5523     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5524     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5525     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5526     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5527     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5528     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5529     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5530     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5531     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5532
5533     hr = IDirect3DDevice9_BeginScene(device);
5534     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5535     if(SUCCEEDED(hr))
5536     {
5537         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5538         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5539         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5540         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5541
5542         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5543         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5545         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5546
5547         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5548         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5549         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5550         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5551
5552         hr = IDirect3DDevice9_EndScene(device);
5553         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5554     }
5555     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5556     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5557
5558     color = getPixelColor(device, 160, 120);
5559     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5560        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5561     color = getPixelColor(device, 160, 360);
5562     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5563        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5564     color = getPixelColor(device, 480, 360);
5565     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5566        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5567
5568     /* cleanup */
5569     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5570     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5571     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5572     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5573     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5574     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5575     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5576     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5577 }
5578
5579 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5580     static const DWORD vs_code[] = {
5581     0xfffe0300,                                                             /* vs_3_0                       */
5582     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5583     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5584     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5585     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5586     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5587     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5588     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5589     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5590     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5591     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5592     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5593     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5594     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5595
5596     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5597     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5598     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5599     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5600     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5601     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5602     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5603     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5604     0x0000ffff                                                              /* end                          */
5605     };
5606     static const DWORD ps_1_code[] = {
5607     0xffff0104,                                                             /* ps_1_4                       */
5608     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5609     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5610     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5611     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5612     0x0000ffff                                                              /* end                          */
5613     };
5614     static const DWORD ps_2_code[] = {
5615     0xffff0200,                                                             /* ps_2_0                       */
5616     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5617     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5618     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5619
5620     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5621     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5622     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5623     0x0000ffff                                                              /* end                          */
5624     };
5625     static const DWORD ps_3_code[] = {
5626     0xffff0300,                                                             /* ps_3_0                       */
5627     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5628     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5629     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5630
5631     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5632     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5633     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5634     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5635     0x0000ffff                                                              /* end                          */
5636     };
5637
5638     float quad1[] =  {
5639         -1.0,   -1.0,   0.1,
5640          0.0,   -1.0,   0.1,
5641         -1.0,    0.0,   0.1,
5642          0.0,    0.0,   0.1
5643     };
5644     float quad2[] =  {
5645          0.0,   -1.0,   0.1,
5646          1.0,   -1.0,   0.1,
5647          0.0,    0.0,   0.1,
5648          1.0,    0.0,   0.1
5649     };
5650     float quad3[] =  {
5651         -1.0,    0.0,   0.1,
5652          0.0,    0.0,   0.1,
5653         -1.0,    1.0,   0.1,
5654          0.0,    1.0,   0.1
5655     };
5656     float quad4[] =  {
5657          0.0,    0.0,   0.1,
5658          1.0,    0.0,   0.1,
5659          0.0,    1.0,   0.1,
5660          1.0,    1.0,   0.1
5661     };
5662
5663     HRESULT hr;
5664     DWORD color;
5665     IDirect3DVertexShader9 *vertexshader = NULL;
5666     IDirect3DPixelShader9 *ps_1_shader = NULL;
5667     IDirect3DPixelShader9 *ps_2_shader = NULL;
5668     IDirect3DPixelShader9 *ps_3_shader = NULL;
5669     IDirect3DTexture9 *texture = NULL;
5670     D3DLOCKED_RECT lr;
5671     unsigned int x, y;
5672
5673     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5674
5675     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5676     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5677     if(FAILED(hr)) {
5678         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5679         return;
5680     }
5681     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5682     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5683     for(y = 0; y < 512; y++) {
5684         for(x = 0; x < 512; x++) {
5685             double r_f = (double) x / (double) 512;
5686             double g_f = (double) y / (double) 512;
5687             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5688             unsigned short r = (unsigned short) (r_f * 65535.0);
5689             unsigned short g = (unsigned short) (g_f * 65535.0);
5690             dst[0] = r;
5691             dst[1] = g;
5692             dst[2] = 0;
5693             dst[3] = 65535;
5694         }
5695     }
5696     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5697     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5698
5699     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5700     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5701     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5702     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5703     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5704     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5705     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5706     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5707     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5708     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5709     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5710
5711     hr = IDirect3DDevice9_BeginScene(device);
5712     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5713     if(SUCCEEDED(hr))
5714     {
5715         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5716         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5717         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5718         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5719
5720         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5721         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5722         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5723         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5724
5725         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5726         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5727         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5728         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5729
5730         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5731         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5732         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5733         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5734         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5735         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5736         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5737         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5738         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5739         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5740
5741         hr = IDirect3DDevice9_EndScene(device);
5742         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5743     }
5744     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5745     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5746
5747     color = getPixelColor(device, 160, 120);
5748     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5749        (color & 0x0000ff00) == 0x0000ff00 &&
5750        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5751        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5752     color = getPixelColor(device, 160, 360);
5753     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5754        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5755        (color & 0x000000ff) == 0x00000000,
5756        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5757     color = getPixelColor(device, 480, 360);
5758     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5759        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5760        (color & 0x000000ff) == 0x00000000,
5761        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5762     color = getPixelColor(device, 480, 160);
5763     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5764        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5765        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5766        (color & 0x000000ff) == 0x00000000),
5767        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5768
5769     /* cleanup */
5770     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5771     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5772     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5773     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5774     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5775     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5776     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5777     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5778     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5779     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5780     if(texture) IDirect3DTexture9_Release(texture);
5781 }
5782
5783 static void test_compare_instructions(IDirect3DDevice9 *device)
5784 {
5785     DWORD shader_sge_vec_code[] = {
5786         0xfffe0101,                                         /* vs_1_1                   */
5787         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5788         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5789         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5790         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5791         0x0000ffff                                          /* end                      */
5792     };
5793     DWORD shader_slt_vec_code[] = {
5794         0xfffe0101,                                         /* vs_1_1                   */
5795         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5796         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5797         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5798         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5799         0x0000ffff                                          /* end                      */
5800     };
5801     DWORD shader_sge_scalar_code[] = {
5802         0xfffe0101,                                         /* vs_1_1                   */
5803         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5804         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5805         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5806         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5807         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5808         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5809         0x0000ffff                                          /* end                      */
5810     };
5811     DWORD shader_slt_scalar_code[] = {
5812         0xfffe0101,                                         /* vs_1_1                   */
5813         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5814         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5815         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5816         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5817         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5818         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5819         0x0000ffff                                          /* end                      */
5820     };
5821     IDirect3DVertexShader9 *shader_sge_vec;
5822     IDirect3DVertexShader9 *shader_slt_vec;
5823     IDirect3DVertexShader9 *shader_sge_scalar;
5824     IDirect3DVertexShader9 *shader_slt_scalar;
5825     HRESULT hr, color;
5826     float quad1[] =  {
5827         -1.0,   -1.0,   0.1,
5828          0.0,   -1.0,   0.1,
5829         -1.0,    0.0,   0.1,
5830          0.0,    0.0,   0.1
5831     };
5832     float quad2[] =  {
5833          0.0,   -1.0,   0.1,
5834          1.0,   -1.0,   0.1,
5835          0.0,    0.0,   0.1,
5836          1.0,    0.0,   0.1
5837     };
5838     float quad3[] =  {
5839         -1.0,    0.0,   0.1,
5840          0.0,    0.0,   0.1,
5841         -1.0,    1.0,   0.1,
5842          0.0,    1.0,   0.1
5843     };
5844     float quad4[] =  {
5845          0.0,    0.0,   0.1,
5846          1.0,    0.0,   0.1,
5847          0.0,    1.0,   0.1,
5848          1.0,    1.0,   0.1
5849     };
5850     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5851     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5852
5853     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5854
5855     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5856     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5857     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5858     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5859     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5860     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5861     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5862     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5863     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5864     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5865     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5866     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5867     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5868     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5869
5870     hr = IDirect3DDevice9_BeginScene(device);
5871     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5872     if(SUCCEEDED(hr))
5873     {
5874         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5875         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5876         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5877         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5878
5879         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5880         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5881         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5882         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5883
5884         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5885         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5886         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5887         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5888
5889         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5890         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5891
5892         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5893         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5895         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5896
5897         hr = IDirect3DDevice9_EndScene(device);
5898         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5899     }
5900
5901     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5902     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5903     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5904     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5905
5906     color = getPixelColor(device, 160, 360);
5907     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5908     color = getPixelColor(device, 480, 360);
5909     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5910     color = getPixelColor(device, 160, 120);
5911     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5912     color = getPixelColor(device, 480, 160);
5913     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5914
5915     IDirect3DVertexShader9_Release(shader_sge_vec);
5916     IDirect3DVertexShader9_Release(shader_slt_vec);
5917     IDirect3DVertexShader9_Release(shader_sge_scalar);
5918     IDirect3DVertexShader9_Release(shader_slt_scalar);
5919 }
5920
5921 static void test_vshader_input(IDirect3DDevice9 *device)
5922 {
5923     DWORD swapped_shader_code_3[] = {
5924         0xfffe0300,                                         /* vs_3_0               */
5925         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5926         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5927         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5928         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5929         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5930         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5931         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5932         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5933         0x0000ffff                                          /* end                  */
5934     };
5935     DWORD swapped_shader_code_1[] = {
5936         0xfffe0101,                                         /* vs_1_1               */
5937         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5938         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5939         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5940         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5941         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5942         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5943         0x0000ffff                                          /* end                  */
5944     };
5945     DWORD swapped_shader_code_2[] = {
5946         0xfffe0200,                                         /* vs_2_0               */
5947         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5948         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5949         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5950         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5951         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5952         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5953         0x0000ffff                                          /* end                  */
5954     };
5955     DWORD texcoord_color_shader_code_3[] = {
5956         0xfffe0300,                                         /* vs_3_0               */
5957         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5958         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5959         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5960         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5961         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5962         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5963         0x0000ffff                                          /* end                  */
5964     };
5965     DWORD texcoord_color_shader_code_2[] = {
5966         0xfffe0200,                                         /* vs_2_0               */
5967         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5968         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5969         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5970         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5971         0x0000ffff                                          /* end                  */
5972     };
5973     DWORD texcoord_color_shader_code_1[] = {
5974         0xfffe0101,                                         /* vs_1_1               */
5975         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5976         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5977         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5978         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5979         0x0000ffff                                          /* end                  */
5980     };
5981     DWORD color_color_shader_code_3[] = {
5982         0xfffe0300,                                         /* vs_3_0               */
5983         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5984         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5985         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5986         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5987         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5988         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5989         0x0000ffff                                          /* end                  */
5990     };
5991     DWORD color_color_shader_code_2[] = {
5992         0xfffe0200,                                         /* vs_2_0               */
5993         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5994         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5995         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5996         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5997         0x0000ffff                                          /* end                  */
5998     };
5999     DWORD color_color_shader_code_1[] = {
6000         0xfffe0101,                                         /* vs_1_1               */
6001         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6002         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6003         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6004         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6005         0x0000ffff                                          /* end                  */
6006     };
6007     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6008     HRESULT hr;
6009     DWORD color;
6010     float quad1[] =  {
6011         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6012          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6013         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6014          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6015     };
6016     float quad2[] =  {
6017          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6018          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6019          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6020          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6021     };
6022     float quad3[] =  {
6023         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6024          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6025         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6026          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6027     };
6028     float quad4[] =  {
6029          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6030          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6031          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6032          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6033     };
6034     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6035         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6036         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6037         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6038         D3DDECL_END()
6039     };
6040     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6041         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6042         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6043         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6044         D3DDECL_END()
6045     };
6046     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6047         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6048         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6049         D3DDECL_END()
6050     };
6051     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6052         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6053         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6054         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6055         D3DDECL_END()
6056     };
6057     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6058         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6059         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6060         D3DDECL_END()
6061     };
6062     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6063         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6064         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6065         D3DDECL_END()
6066     };
6067     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6068         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6069         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6070         D3DDECL_END()
6071     };
6072     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6073         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6074         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6075         D3DDECL_END()
6076     };
6077     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6078     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6079     unsigned int i;
6080     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6081     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6082
6083     struct vertex quad1_color[] =  {
6084        {-1.0,   -1.0,   0.1,    0x00ff8040},
6085        { 0.0,   -1.0,   0.1,    0x00ff8040},
6086        {-1.0,    0.0,   0.1,    0x00ff8040},
6087        { 0.0,    0.0,   0.1,    0x00ff8040}
6088     };
6089     struct vertex quad2_color[] =  {
6090        { 0.0,   -1.0,   0.1,    0x00ff8040},
6091        { 1.0,   -1.0,   0.1,    0x00ff8040},
6092        { 0.0,    0.0,   0.1,    0x00ff8040},
6093        { 1.0,    0.0,   0.1,    0x00ff8040}
6094     };
6095     struct vertex quad3_color[] =  {
6096        {-1.0,    0.0,   0.1,    0x00ff8040},
6097        { 0.0,    0.0,   0.1,    0x00ff8040},
6098        {-1.0,    1.0,   0.1,    0x00ff8040},
6099        { 0.0,    1.0,   0.1,    0x00ff8040}
6100     };
6101     float quad4_color[] =  {
6102          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6103          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6104          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6105          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6106     };
6107
6108     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6109     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6110     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6111     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6112     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6113     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6114     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6115     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6116
6117     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6118     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6119     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6120     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6121     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6122     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6123     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6124     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6125
6126     for(i = 1; i <= 3; i++) {
6127         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6128         if(i == 3) {
6129             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6130             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6131         } else if(i == 2){
6132             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6133             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6134         } else if(i == 1) {
6135             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6136             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6137         }
6138
6139         hr = IDirect3DDevice9_BeginScene(device);
6140         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6141         if(SUCCEEDED(hr))
6142         {
6143             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6144             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6145
6146             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6147             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6148             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6149             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6150
6151             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6152             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6153             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6154             if(i == 3 || i == 2) {
6155                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6156             } else if(i == 1) {
6157                 /* Succeeds or fails, depending on SW or HW vertex processing */
6158                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6159             }
6160
6161             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6162             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6163             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6164             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6165
6166             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6167             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6168             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6169             if(i == 3 || i == 2) {
6170                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6171             } else if(i == 1) {
6172                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6173             }
6174
6175             hr = IDirect3DDevice9_EndScene(device);
6176             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6177         }
6178
6179         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6180         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6181
6182         if(i == 3 || i == 2) {
6183             color = getPixelColor(device, 160, 360);
6184             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6185                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6186
6187             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6188             color = getPixelColor(device, 480, 360);
6189             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6190                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6191             color = getPixelColor(device, 160, 120);
6192             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6193             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6194                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6195
6196             color = getPixelColor(device, 480, 160);
6197             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6198         } else if(i == 1) {
6199             color = getPixelColor(device, 160, 360);
6200             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6201                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6202             color = getPixelColor(device, 480, 360);
6203             /* Accept the clear color as well in this case, since SW VP returns an error */
6204             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6205             color = getPixelColor(device, 160, 120);
6206             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6207                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6208             color = getPixelColor(device, 480, 160);
6209             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6210         }
6211
6212         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6213         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6214
6215         /* Now find out if the whole streams are re-read, or just the last active value for the
6216          * vertices is used.
6217          */
6218         hr = IDirect3DDevice9_BeginScene(device);
6219         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6220         if(SUCCEEDED(hr))
6221         {
6222             float quad1_modified[] =  {
6223                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6224                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6225                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6226                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6227             };
6228             float quad2_modified[] =  {
6229                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6230                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6231                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6232                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6233             };
6234
6235             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6236             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6237
6238             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6239             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6240             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6241             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6242
6243             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6244             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6245             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6246             if(i == 3 || i == 2) {
6247                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6248             } else if(i == 1) {
6249                 /* Succeeds or fails, depending on SW or HW vertex processing */
6250                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6251             }
6252
6253             hr = IDirect3DDevice9_EndScene(device);
6254             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6255         }
6256         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6257         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6258
6259         color = getPixelColor(device, 480, 350);
6260         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6261          * as well.
6262          *
6263          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6264          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6265          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6266          * refrast's result.
6267          *
6268          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6269          */
6270         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6271            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6272         color = getPixelColor(device, 160, 120);
6273
6274         IDirect3DDevice9_SetVertexShader(device, NULL);
6275         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6276
6277         IDirect3DVertexShader9_Release(swapped_shader);
6278     }
6279
6280     for(i = 1; i <= 3; i++) {
6281         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6282         if(i == 3) {
6283             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6284             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6285             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6286             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6287         } else if(i == 2){
6288             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6289             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6290             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6291             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6292         } else if(i == 1) {
6293             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6294             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6295             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6296             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6297         }
6298
6299         hr = IDirect3DDevice9_BeginScene(device);
6300         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6301         if(SUCCEEDED(hr))
6302         {
6303             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6304             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6305             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6306             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6307             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6308             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6309
6310             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6311             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6312
6313             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6314             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6315             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6316             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6317             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6318             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6319
6320             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6321             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6322             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6323             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6324             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6325             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6326
6327             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6328             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6329             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6330             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6331
6332             hr = IDirect3DDevice9_EndScene(device);
6333             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6334         }
6335         IDirect3DDevice9_SetVertexShader(device, NULL);
6336         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6337
6338         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6339         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6340
6341         color = getPixelColor(device, 160, 360);
6342         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6343            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6344         color = getPixelColor(device, 480, 360);
6345         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6346            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6347         color = getPixelColor(device, 160, 120);
6348         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6349            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6350         color = getPixelColor(device, 480, 160);
6351         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6352            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6353
6354         IDirect3DVertexShader9_Release(texcoord_color_shader);
6355         IDirect3DVertexShader9_Release(color_color_shader);
6356     }
6357
6358     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6359     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6360     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6361     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6362
6363     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6364     IDirect3DVertexDeclaration9_Release(decl_color_color);
6365     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6366     IDirect3DVertexDeclaration9_Release(decl_color_float);
6367 }
6368
6369 static void srgbtexture_test(IDirect3DDevice9 *device)
6370 {
6371     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6372      * texture stage state to render a quad using that texture.  The resulting
6373      * color components should be 0x36 (~ 0.21), per this formula:
6374      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6375      * This is true where srgb_color > 0.04045.
6376      */
6377     IDirect3D9 *d3d = NULL;
6378     HRESULT hr;
6379     LPDIRECT3DTEXTURE9 texture = NULL;
6380     LPDIRECT3DSURFACE9 surface = NULL;
6381     D3DLOCKED_RECT lr;
6382     DWORD color;
6383     float quad[] = {
6384         -1.0,       1.0,       0.0,     0.0,    0.0,
6385          1.0,       1.0,       0.0,     1.0,    0.0,
6386         -1.0,      -1.0,       0.0,     0.0,    1.0,
6387          1.0,      -1.0,       0.0,     1.0,    1.0,
6388     };
6389
6390
6391     memset(&lr, 0, sizeof(lr));
6392     IDirect3DDevice9_GetDirect3D(device, &d3d);
6393     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6394                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6395                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6396         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6397         goto out;
6398     }
6399
6400     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6401                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6402                                         &texture, NULL);
6403     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6404     if(!texture) {
6405         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6406         goto out;
6407     }
6408     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6409     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6410
6411     fill_surface(surface, 0xff7f7f7f);
6412     IDirect3DSurface9_Release(surface);
6413
6414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6415     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6416     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6417     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6418
6419     hr = IDirect3DDevice9_BeginScene(device);
6420     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6421     if(SUCCEEDED(hr))
6422     {
6423         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6424         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6425
6426         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6427         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6428
6429
6430         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6431         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6432
6433         hr = IDirect3DDevice9_EndScene(device);
6434         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6435     }
6436
6437     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6438     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6439     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6440     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6441
6442     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6443     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6444
6445     color = getPixelColor(device, 320, 240);
6446     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6447
6448 out:
6449     if(texture) IDirect3DTexture9_Release(texture);
6450     IDirect3D9_Release(d3d);
6451 }
6452
6453 static void shademode_test(IDirect3DDevice9 *device)
6454 {
6455     /* Render a quad and try all of the different fixed function shading models. */
6456     HRESULT hr;
6457     DWORD color0, color1;
6458     DWORD color0_gouraud = 0, color1_gouraud = 0;
6459     DWORD shademode = D3DSHADE_FLAT;
6460     DWORD primtype = D3DPT_TRIANGLESTRIP;
6461     LPVOID data = NULL;
6462     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6463     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6464     UINT i, j;
6465     struct vertex quad_strip[] =
6466     {
6467         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6468         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6469         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6470         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6471     };
6472     struct vertex quad_list[] =
6473     {
6474         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6475         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6476         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6477
6478         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6479         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6480         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6481     };
6482
6483     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6484                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6485     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6486     if (FAILED(hr)) goto bail;
6487
6488     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6489                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6490     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6491     if (FAILED(hr)) goto bail;
6492
6493     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6494     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6495
6496     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6497     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6498
6499     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6500     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6501     memcpy(data, quad_strip, sizeof(quad_strip));
6502     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6503     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6504
6505     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6506     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6507     memcpy(data, quad_list, sizeof(quad_list));
6508     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6509     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6510
6511     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6512      * the color fixups we have to do for FLAT shading will be dependent on that. */
6513     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6514     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6515
6516     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6517     for (j=0; j<2; j++) {
6518
6519         /* Inner loop just changes the D3DRS_SHADEMODE */
6520         for (i=0; i<3; i++) {
6521             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6522             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6523
6524             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6525             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6526
6527             hr = IDirect3DDevice9_BeginScene(device);
6528             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6529             if(SUCCEEDED(hr))
6530             {
6531                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6532                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6533
6534                 hr = IDirect3DDevice9_EndScene(device);
6535                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6536             }
6537
6538             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6539             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6540
6541             /* Sample two spots from the output */
6542             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6543             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6544             switch(shademode) {
6545                 case D3DSHADE_FLAT:
6546                     /* Should take the color of the first vertex of each triangle */
6547                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6548                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6549                     shademode = D3DSHADE_GOURAUD;
6550                     break;
6551                 case D3DSHADE_GOURAUD:
6552                     /* Should be an interpolated blend */
6553
6554                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6555                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6556                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6557                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6558
6559                     color0_gouraud = color0;
6560                     color1_gouraud = color1;
6561
6562                     shademode = D3DSHADE_PHONG;
6563                     break;
6564                 case D3DSHADE_PHONG:
6565                     /* Should be the same as GOURAUD, since no hardware implements this */
6566                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6567                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6568                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6569                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6570
6571                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6572                             color0_gouraud, color0);
6573                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6574                             color1_gouraud, color1);
6575                     break;
6576             }
6577         }
6578         /* Now, do it all over again with a TRIANGLELIST */
6579         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6580         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6581         primtype = D3DPT_TRIANGLELIST;
6582         shademode = D3DSHADE_FLAT;
6583     }
6584
6585 bail:
6586     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6587     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6588     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6589     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6590
6591     if (vb_strip)
6592         IDirect3DVertexBuffer9_Release(vb_strip);
6593     if (vb_list)
6594         IDirect3DVertexBuffer9_Release(vb_list);
6595 }
6596
6597
6598 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6599 {
6600     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6601      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6602      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6603      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6604      * 0.73
6605      *
6606      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6607      * so use shaders for this task
6608      */
6609     IDirect3DPixelShader9 *pshader;
6610     IDirect3DVertexShader9 *vshader;
6611     IDirect3D9 *d3d;
6612     DWORD vshader_code[] = {
6613         0xfffe0101,                                                             /* vs_1_1                       */
6614         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6615         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6616         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6617         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6618         0x0000ffff                                                              /* end                          */
6619     };
6620     DWORD pshader_code[] = {
6621         0xffff0101,                                                             /* ps_1_1                       */
6622         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6623         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6624         0x0000ffff                                                              /* end                          */
6625     };
6626     const float quad[] = {
6627        -1.0,   -1.0,    0.1,
6628         1.0,   -1.0,    0.1,
6629        -1.0,    1.0,    0.1,
6630         1.0,    1.0,    0.1
6631     };
6632     HRESULT hr;
6633     DWORD color;
6634
6635     IDirect3DDevice9_GetDirect3D(device, &d3d);
6636     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6637      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6638      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6639      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6640      * works
6641      */
6642     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6643                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6644                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6645         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6646         IDirect3D9_Release(d3d);
6647         return;
6648     }
6649     IDirect3D9_Release(d3d);
6650
6651     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6652     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6653
6654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6655     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6657     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6658     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6659     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6661     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6663     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6664
6665     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6666     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6667     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6668     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6669     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6670     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6671     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6672     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6673     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6674     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6675
6676     hr = IDirect3DDevice9_BeginScene(device);
6677     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6678     if(SUCCEEDED(hr)) {
6679         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6680         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6681
6682         hr = IDirect3DDevice9_EndScene(device);
6683         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6684     }
6685
6686     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6687     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6688     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6689     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6690     IDirect3DPixelShader9_Release(pshader);
6691     IDirect3DVertexShader9_Release(vshader);
6692
6693     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6694     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6695     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6696     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6697
6698     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6699     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6700     color = getPixelColor(device, 160, 360);
6701     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6702        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6703 }
6704
6705 static void alpha_test(IDirect3DDevice9 *device)
6706 {
6707     HRESULT hr;
6708     IDirect3DTexture9 *offscreenTexture;
6709     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6710     DWORD color;
6711
6712     struct vertex quad1[] =
6713     {
6714         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6715         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6716         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6717         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6718     };
6719     struct vertex quad2[] =
6720     {
6721         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6722         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6723         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6724         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6725     };
6726     static const float composite_quad[][5] = {
6727         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6728         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6729         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6730         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6731     };
6732
6733     /* Clear the render target with alpha = 0.5 */
6734     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6735     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6736
6737     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6738     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6739
6740     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6741     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6742     if(!backbuffer) {
6743         goto out;
6744     }
6745
6746     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6747     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6748     if(!offscreen) {
6749         goto out;
6750     }
6751
6752     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6753     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6754
6755     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6756     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6757     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6758     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6759     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6760     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6761     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6762     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6763     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6764     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6765
6766     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6767     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6769
6770         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6771         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6772         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6773         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6774         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6776         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6777
6778         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6779         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6780         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6781         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6783         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6784
6785         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6786          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6787          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6788         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6789         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6790         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6791         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6792
6793         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6794         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6795         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6796         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6797         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6798         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6799
6800         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6801         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6802         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6803         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6804         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6805         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6806
6807         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6808         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6809
6810         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6811          * Disable alpha blending for the final composition
6812          */
6813         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6814         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6815         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6816         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6817
6818         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6819         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6820         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6821         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6822         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6823         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6824
6825         hr = IDirect3DDevice9_EndScene(device);
6826         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6827     }
6828
6829     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6830
6831     color = getPixelColor(device, 160, 360);
6832     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6833        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6834
6835     color = getPixelColor(device, 160, 120);
6836     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6837        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6838
6839     color = getPixelColor(device, 480, 360);
6840     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6841        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6842
6843     color = getPixelColor(device, 480, 120);
6844     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6845        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6846
6847     out:
6848     /* restore things */
6849     if(backbuffer) {
6850         IDirect3DSurface9_Release(backbuffer);
6851     }
6852     if(offscreenTexture) {
6853         IDirect3DTexture9_Release(offscreenTexture);
6854     }
6855     if(offscreen) {
6856         IDirect3DSurface9_Release(offscreen);
6857     }
6858 }
6859
6860 struct vertex_shortcolor {
6861     float x, y, z;
6862     unsigned short r, g, b, a;
6863 };
6864 struct vertex_floatcolor {
6865     float x, y, z;
6866     float r, g, b, a;
6867 };
6868
6869 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6870 {
6871     HRESULT hr;
6872     BOOL s_ok, ub_ok, f_ok;
6873     DWORD color, size, i;
6874     void *data;
6875     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6876         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6877         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6878         D3DDECL_END()
6879     };
6880     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6881         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6882         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6883         D3DDECL_END()
6884     };
6885     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6886         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6887         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6888         D3DDECL_END()
6889     };
6890     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6891         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6892         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6893         D3DDECL_END()
6894     };
6895     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6896         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6897         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6898         D3DDECL_END()
6899     };
6900     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6901         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6902         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6903         D3DDECL_END()
6904     };
6905     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6906         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6907         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6908         D3DDECL_END()
6909     };
6910     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6911     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6912     IDirect3DVertexBuffer9 *vb, *vb2;
6913     struct vertex quad1[] =                             /* D3DCOLOR */
6914     {
6915         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6916         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6917         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6918         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6919     };
6920     struct vertex quad2[] =                             /* UBYTE4N */
6921     {
6922         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6923         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6924         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6925         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6926     };
6927     struct vertex_shortcolor quad3[] =                  /* short */
6928     {
6929         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6930         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6931         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6932         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6933     };
6934     struct vertex_floatcolor quad4[] =
6935     {
6936         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6937         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6938         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6939         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6940     };
6941     DWORD colors[] = {
6942         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6943         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6944         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6945         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6946         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6947         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6948         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6949         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6950         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6951         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6952         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6953         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6954         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6955         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6956         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6957         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6958     };
6959     float quads[] = {
6960         -1.0,   -1.0,     0.1,
6961         -1.0,    0.0,     0.1,
6962          0.0,   -1.0,     0.1,
6963          0.0,    0.0,     0.1,
6964
6965          0.0,   -1.0,     0.1,
6966          0.0,    0.0,     0.1,
6967          1.0,   -1.0,     0.1,
6968          1.0,    0.0,     0.1,
6969
6970          0.0,    0.0,     0.1,
6971          0.0,    1.0,     0.1,
6972          1.0,    0.0,     0.1,
6973          1.0,    1.0,     0.1,
6974
6975         -1.0,    0.0,     0.1,
6976         -1.0,    1.0,     0.1,
6977          0.0,    0.0,     0.1,
6978          0.0,    1.0,     0.1
6979     };
6980     struct tvertex quad_transformed[] = {
6981        {  90,    110,     0.1,      2.0,        0x00ffff00},
6982        { 570,    110,     0.1,      2.0,        0x00ffff00},
6983        {  90,    300,     0.1,      2.0,        0x00ffff00},
6984        { 570,    300,     0.1,      2.0,        0x00ffff00}
6985     };
6986     D3DCAPS9 caps;
6987
6988     memset(&caps, 0, sizeof(caps));
6989     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6990     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6991
6992     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6993     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6994
6995     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6996     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6997     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6998     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6999     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7000     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7001     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7002         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7003         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7004         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7005         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7006     } else {
7007         trace("D3DDTCAPS_UBYTE4N not supported\n");
7008         dcl_ubyte_2 = NULL;
7009         dcl_ubyte = NULL;
7010     }
7011     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7012     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7013     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7014     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7015
7016     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7017     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7018                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7019     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7020
7021     hr = IDirect3DDevice9_BeginScene(device);
7022     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7023     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7024     if(SUCCEEDED(hr)) {
7025         if(dcl_color) {
7026             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7027             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7028             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7029             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7030         }
7031
7032         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7033          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7034          * using software vertex processing. Doh!
7035          */
7036         if(dcl_ubyte) {
7037             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7038             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7039             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7040             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7041             ub_ok = SUCCEEDED(hr);
7042         }
7043
7044         if(dcl_short) {
7045             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7046             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7047             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7048             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7049             s_ok = SUCCEEDED(hr);
7050         }
7051
7052         if(dcl_float) {
7053             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7054             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7055             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7056             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7057             f_ok = SUCCEEDED(hr);
7058         }
7059
7060         hr = IDirect3DDevice9_EndScene(device);
7061         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7062     }
7063
7064     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7065     if(dcl_short) {
7066         color = getPixelColor(device, 480, 360);
7067         ok(color == 0x000000ff || !s_ok,
7068            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7069     }
7070     if(dcl_ubyte) {
7071         color = getPixelColor(device, 160, 120);
7072         ok(color == 0x0000ffff || !ub_ok,
7073            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7074     }
7075     if(dcl_color) {
7076         color = getPixelColor(device, 160, 360);
7077         ok(color == 0x00ffff00,
7078            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7079     }
7080     if(dcl_float) {
7081         color = getPixelColor(device, 480, 120);
7082         ok(color == 0x00ff0000 || !f_ok,
7083            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7084     }
7085
7086     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7087      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7088      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7089      * whether the immediate mode code works
7090      */
7091     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7092     hr = IDirect3DDevice9_BeginScene(device);
7093     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7094     if(SUCCEEDED(hr)) {
7095         if(dcl_color) {
7096             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7097             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7098             memcpy(data, quad1, sizeof(quad1));
7099             hr = IDirect3DVertexBuffer9_Unlock(vb);
7100             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7101             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7102             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7103             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7104             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7105             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7106             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7107         }
7108
7109         if(dcl_ubyte) {
7110             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7111             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7112             memcpy(data, quad2, sizeof(quad2));
7113             hr = IDirect3DVertexBuffer9_Unlock(vb);
7114             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7115             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7116             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7117             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7118             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7119             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7120             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7121                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7122             ub_ok = SUCCEEDED(hr);
7123         }
7124
7125         if(dcl_short) {
7126             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7127             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7128             memcpy(data, quad3, sizeof(quad3));
7129             hr = IDirect3DVertexBuffer9_Unlock(vb);
7130             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7131             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7132             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7133             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7134             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7135             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7136             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7137                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7138             s_ok = SUCCEEDED(hr);
7139         }
7140
7141         if(dcl_float) {
7142             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7143             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7144             memcpy(data, quad4, sizeof(quad4));
7145             hr = IDirect3DVertexBuffer9_Unlock(vb);
7146             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7147             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7148             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7149             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7150             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7151             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7152             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7153                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7154             f_ok = SUCCEEDED(hr);
7155         }
7156
7157         hr = IDirect3DDevice9_EndScene(device);
7158         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7159     }
7160
7161     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7162     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7163     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7164     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7165
7166     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7167     if(dcl_short) {
7168         color = getPixelColor(device, 480, 360);
7169         ok(color == 0x000000ff || !s_ok,
7170            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7171     }
7172     if(dcl_ubyte) {
7173         color = getPixelColor(device, 160, 120);
7174         ok(color == 0x0000ffff || !ub_ok,
7175            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7176     }
7177     if(dcl_color) {
7178         color = getPixelColor(device, 160, 360);
7179         ok(color == 0x00ffff00,
7180            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7181     }
7182     if(dcl_float) {
7183         color = getPixelColor(device, 480, 120);
7184         ok(color == 0x00ff0000 || !f_ok,
7185            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7186     }
7187
7188     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7189     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7190
7191     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7192     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7193     memcpy(data, quad_transformed, sizeof(quad_transformed));
7194     hr = IDirect3DVertexBuffer9_Unlock(vb);
7195     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7196
7197     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7198     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7199
7200     hr = IDirect3DDevice9_BeginScene(device);
7201     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7202     if(SUCCEEDED(hr)) {
7203         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7204         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7205         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7206         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7207
7208         hr = IDirect3DDevice9_EndScene(device);
7209         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7210     }
7211
7212     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7213     color = getPixelColor(device, 88, 108);
7214     ok(color == 0x000000ff,
7215        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7216     color = getPixelColor(device, 92, 108);
7217     ok(color == 0x000000ff,
7218        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7219     color = getPixelColor(device, 88, 112);
7220     ok(color == 0x000000ff,
7221        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7222     color = getPixelColor(device, 92, 112);
7223     ok(color == 0x00ffff00,
7224        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7225
7226     color = getPixelColor(device, 568, 108);
7227     ok(color == 0x000000ff,
7228        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7229     color = getPixelColor(device, 572, 108);
7230     ok(color == 0x000000ff,
7231        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7232     color = getPixelColor(device, 568, 112);
7233     ok(color == 0x00ffff00,
7234        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7235     color = getPixelColor(device, 572, 112);
7236     ok(color == 0x000000ff,
7237        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7238
7239     color = getPixelColor(device, 88, 298);
7240     ok(color == 0x000000ff,
7241        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7242     color = getPixelColor(device, 92, 298);
7243     ok(color == 0x00ffff00,
7244        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7245     color = getPixelColor(device, 88, 302);
7246     ok(color == 0x000000ff,
7247        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7248     color = getPixelColor(device, 92, 302);
7249     ok(color == 0x000000ff,
7250        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7251
7252     color = getPixelColor(device, 568, 298);
7253     ok(color == 0x00ffff00,
7254        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7255     color = getPixelColor(device, 572, 298);
7256     ok(color == 0x000000ff,
7257        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7258     color = getPixelColor(device, 568, 302);
7259     ok(color == 0x000000ff,
7260        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7261     color = getPixelColor(device, 572, 302);
7262     ok(color == 0x000000ff,
7263        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7264
7265     /* This test is pointless without those two declarations: */
7266     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7267         skip("color-ubyte switching test declarations aren't supported\n");
7268         goto out;
7269     }
7270
7271     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7272     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7273     memcpy(data, quads, sizeof(quads));
7274     hr = IDirect3DVertexBuffer9_Unlock(vb);
7275     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7276     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7277                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7278     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7279     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7280     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7281     memcpy(data, colors, sizeof(colors));
7282     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7283     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7284
7285     for(i = 0; i < 2; i++) {
7286         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7287         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7288
7289         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7290         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7291         if(i == 0) {
7292             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7293         } else {
7294             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7295         }
7296         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7297
7298         hr = IDirect3DDevice9_BeginScene(device);
7299         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7300         ub_ok = FALSE;
7301         if(SUCCEEDED(hr)) {
7302             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7303             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7304             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7305             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7306                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7307             ub_ok = SUCCEEDED(hr);
7308
7309             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7310             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7311             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7312             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7313
7314             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7315             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7316             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7317             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7318                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7319             ub_ok = (SUCCEEDED(hr) && ub_ok);
7320
7321             hr = IDirect3DDevice9_EndScene(device);
7322             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7323         }
7324
7325         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7326         if(i == 0) {
7327             color = getPixelColor(device, 480, 360);
7328             ok(color == 0x00ff0000,
7329                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7330             color = getPixelColor(device, 160, 120);
7331             ok(color == 0x00ffffff,
7332                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7333             color = getPixelColor(device, 160, 360);
7334             ok(color == 0x000000ff || !ub_ok,
7335                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7336             color = getPixelColor(device, 480, 120);
7337             ok(color == 0x000000ff || !ub_ok,
7338                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7339         } else {
7340             color = getPixelColor(device, 480, 360);
7341             ok(color == 0x000000ff,
7342                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7343             color = getPixelColor(device, 160, 120);
7344             ok(color == 0x00ffffff,
7345                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7346             color = getPixelColor(device, 160, 360);
7347             ok(color == 0x00ff0000 || !ub_ok,
7348                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7349             color = getPixelColor(device, 480, 120);
7350             ok(color == 0x00ff0000 || !ub_ok,
7351                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7352         }
7353     }
7354
7355     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7356     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7357     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7358     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7359     IDirect3DVertexBuffer9_Release(vb2);
7360
7361     out:
7362     IDirect3DVertexBuffer9_Release(vb);
7363     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7364     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7365     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7366     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7367     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7368     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7369     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7370 }
7371
7372 struct vertex_float16color {
7373     float x, y, z;
7374     DWORD c1, c2;
7375 };
7376
7377 static void test_vshader_float16(IDirect3DDevice9 *device)
7378 {
7379     HRESULT hr;
7380     DWORD color;
7381     void *data;
7382     static const D3DVERTEXELEMENT9 decl_elements[] = {
7383         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7384         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7385         D3DDECL_END()
7386     };
7387     IDirect3DVertexDeclaration9 *vdecl = NULL;
7388     IDirect3DVertexBuffer9 *buffer = NULL;
7389     IDirect3DVertexShader9 *shader;
7390     DWORD shader_code[] = {
7391         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7392         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7393         0x90e40001, 0x0000ffff
7394     };
7395     struct vertex_float16color quad[] = {
7396         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7397         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7398         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7399         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7400
7401         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7402         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7403         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7404         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7405
7406         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7407         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7408         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7409         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7410
7411         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7412         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7413         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7414         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7415     };
7416
7417     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7418     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7419
7420     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7421     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7422     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7423     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7424     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7425     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7426
7427     hr = IDirect3DDevice9_BeginScene(device);
7428     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7429     if(SUCCEEDED(hr)) {
7430         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7431         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7433         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7436         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7437         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7438         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7439         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7440
7441         hr = IDirect3DDevice9_EndScene(device);
7442         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7443     }
7444     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7445     color = getPixelColor(device, 480, 360);
7446     ok(color == 0x00ff0000,
7447        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7448     color = getPixelColor(device, 160, 120);
7449     ok(color == 0x00000000,
7450        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7451     color = getPixelColor(device, 160, 360);
7452     ok(color == 0x0000ff00,
7453        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7454     color = getPixelColor(device, 480, 120);
7455     ok(color == 0x000000ff,
7456        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7457
7458     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7459     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7460
7461     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7462                                              D3DPOOL_MANAGED, &buffer, NULL);
7463     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7464     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7465     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7466     memcpy(data, quad, sizeof(quad));
7467     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7468     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7469     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7470     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7471
7472     hr = IDirect3DDevice9_BeginScene(device);
7473     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7474     if(SUCCEEDED(hr)) {
7475             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7476             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7477             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7478             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7479             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7480             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7481             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7482             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7483
7484             hr = IDirect3DDevice9_EndScene(device);
7485             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7486     }
7487
7488     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7489     color = getPixelColor(device, 480, 360);
7490     ok(color == 0x00ff0000,
7491        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7492     color = getPixelColor(device, 160, 120);
7493     ok(color == 0x00000000,
7494        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7495     color = getPixelColor(device, 160, 360);
7496     ok(color == 0x0000ff00,
7497        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7498     color = getPixelColor(device, 480, 120);
7499     ok(color == 0x000000ff,
7500        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7501
7502     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7503     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7504     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7505     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7506     IDirect3DDevice9_SetVertexShader(device, NULL);
7507     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7508
7509     IDirect3DVertexDeclaration9_Release(vdecl);
7510     IDirect3DVertexShader9_Release(shader);
7511     IDirect3DVertexBuffer9_Release(buffer);
7512 }
7513
7514 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7515 {
7516     D3DCAPS9 caps;
7517     IDirect3DTexture9 *texture;
7518     HRESULT hr;
7519     D3DLOCKED_RECT rect;
7520     unsigned int x, y;
7521     DWORD *dst, color;
7522     const float quad[] = {
7523         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7524          1.0,   -1.0,   0.1,    1.2,   -0.2,
7525         -1.0,    1.0,   0.1,   -0.2,    1.2,
7526          1.0,    1.0,   0.1,    1.2,    1.2
7527     };
7528     memset(&caps, 0, sizeof(caps));
7529
7530     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7531     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7532     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7533         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7534         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7535            "Card has conditional NP2 support without power of two restriction set\n");
7536         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7537         return;
7538     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7539         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7540         return;
7541     }
7542
7543     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7544     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7545
7546     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7547     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7548
7549     memset(&rect, 0, sizeof(rect));
7550     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7551     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7552     for(y = 0; y < 10; y++) {
7553         for(x = 0; x < 10; x++) {
7554             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7555             if(x == 0 || x == 9 || y == 0 || y == 9) {
7556                 *dst = 0x00ff0000;
7557             } else {
7558                 *dst = 0x000000ff;
7559             }
7560         }
7561     }
7562     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7563     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7564
7565     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7566     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7567     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7568     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7569     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7570     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7571     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7572     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7573
7574     hr = IDirect3DDevice9_BeginScene(device);
7575     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7576     if(SUCCEEDED(hr)) {
7577         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7578         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7579
7580         hr = IDirect3DDevice9_EndScene(device);
7581         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7582     }
7583
7584     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7585
7586     color = getPixelColor(device,    1,  1);
7587     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7588     color = getPixelColor(device, 639, 479);
7589     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7590
7591     color = getPixelColor(device, 135, 101);
7592     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7593     color = getPixelColor(device, 140, 101);
7594     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7595     color = getPixelColor(device, 135, 105);
7596     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7597     color = getPixelColor(device, 140, 105);
7598     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7599
7600     color = getPixelColor(device, 135, 376);
7601     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7602     color = getPixelColor(device, 140, 376);
7603     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7604     color = getPixelColor(device, 135, 379);
7605     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7606     color = getPixelColor(device, 140, 379);
7607     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7608
7609     color = getPixelColor(device, 500, 101);
7610     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7611     color = getPixelColor(device, 504, 101);
7612     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7613     color = getPixelColor(device, 500, 105);
7614     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7615     color = getPixelColor(device, 504, 105);
7616     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7617
7618     color = getPixelColor(device, 500, 376);
7619     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7620     color = getPixelColor(device, 504, 376);
7621     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7622     color = getPixelColor(device, 500, 380);
7623     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7624     color = getPixelColor(device, 504, 380);
7625     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7626
7627     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7628     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7629     IDirect3DTexture9_Release(texture);
7630 }
7631
7632 static void vFace_register_test(IDirect3DDevice9 *device)
7633 {
7634     HRESULT hr;
7635     DWORD color;
7636     const DWORD shader_code[] = {
7637         0xffff0300,                                                             /* ps_3_0                     */
7638         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7639         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7640         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7641         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7642         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7643         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7644         0x0000ffff                                                              /* END                        */
7645     };
7646     IDirect3DPixelShader9 *shader;
7647     IDirect3DTexture9 *texture;
7648     IDirect3DSurface9 *surface, *backbuffer;
7649     const float quad[] = {
7650         -1.0,   -1.0,   0.1,
7651          1.0,   -1.0,   0.1,
7652         -1.0,    0.0,   0.1,
7653
7654          1.0,   -1.0,   0.1,
7655          1.0,    0.0,   0.1,
7656         -1.0,    0.0,   0.1,
7657
7658         -1.0,    0.0,   0.1,
7659         -1.0,    1.0,   0.1,
7660          1.0,    0.0,   0.1,
7661
7662          1.0,    0.0,   0.1,
7663         -1.0,    1.0,   0.1,
7664          1.0,    1.0,   0.1,
7665     };
7666     const float blit[] = {
7667          0.0,   -1.0,   0.1,    0.0,    0.0,
7668          1.0,   -1.0,   0.1,    1.0,    0.0,
7669          0.0,    1.0,   0.1,    0.0,    1.0,
7670          1.0,    1.0,   0.1,    1.0,    1.0,
7671     };
7672
7673     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7674     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7675     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7676     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7677     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7678     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7679     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7680     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7681     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7682     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7683     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7684     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7685
7686     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7687     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7688
7689     hr = IDirect3DDevice9_BeginScene(device);
7690     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7691     if(SUCCEEDED(hr)) {
7692         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7693         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7694         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7695         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7696         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7697         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7698         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7699         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7700         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7701         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7702         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7703
7704         /* Blit the texture onto the back buffer to make it visible */
7705         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7706         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7707         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7708         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7709         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7710         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7711         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7712         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7713         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7714         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7715
7716         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7717         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7718
7719         hr = IDirect3DDevice9_EndScene(device);
7720         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7721     }
7722
7723     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7724     color = getPixelColor(device, 160, 360);
7725     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7726     color = getPixelColor(device, 160, 120);
7727     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7728     color = getPixelColor(device, 480, 360);
7729     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7730     color = getPixelColor(device, 480, 120);
7731     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7732
7733     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7734     IDirect3DDevice9_SetTexture(device, 0, NULL);
7735     IDirect3DPixelShader9_Release(shader);
7736     IDirect3DSurface9_Release(surface);
7737     IDirect3DSurface9_Release(backbuffer);
7738     IDirect3DTexture9_Release(texture);
7739 }
7740
7741 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7742 {
7743     HRESULT hr;
7744     DWORD color;
7745     int i;
7746     D3DCAPS9 caps;
7747     BOOL L6V5U5_supported = FALSE;
7748     IDirect3DTexture9 *tex1, *tex2;
7749     D3DLOCKED_RECT locked_rect;
7750
7751     static const float quad[][7] = {
7752         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7753         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7754         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7755         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7756     };
7757
7758     static const D3DVERTEXELEMENT9 decl_elements[] = {
7759         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7760         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7761         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7762         D3DDECL_END()
7763     };
7764
7765     /* use asymmetric matrix to test loading */
7766     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7767     float scale, offset;
7768
7769     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7770     IDirect3DTexture9           *texture            = NULL;
7771
7772     memset(&caps, 0, sizeof(caps));
7773     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7774     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7775     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7776         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7777         return;
7778     } else {
7779         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7780          * They report that it is not supported, but after that bump mapping works properly. So just test
7781          * if the format is generally supported, and check the BUMPENVMAP flag
7782          */
7783         IDirect3D9 *d3d9;
7784
7785         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7786         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7787                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7788         L6V5U5_supported = SUCCEEDED(hr);
7789         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7790                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7791         IDirect3D9_Release(d3d9);
7792         if(FAILED(hr)) {
7793             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7794             return;
7795         }
7796     }
7797
7798     /* Generate the textures */
7799     generate_bumpmap_textures(device);
7800
7801     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7802     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7803     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7804     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7805     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7806     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7807     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7808     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7809
7810     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7811     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7812     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7813     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7815     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7816
7817     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7818     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7819     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7820     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7821     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7822     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7823
7824     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7825     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7826
7827     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7828     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7829
7830     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7831     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7832
7833
7834     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7835     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7836     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7837     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7838
7839     hr = IDirect3DDevice9_BeginScene(device);
7840     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7841
7842     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7843     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7844
7845     hr = IDirect3DDevice9_EndScene(device);
7846     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7847
7848     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7849     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7850
7851     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7852      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7853      * But since testing the color match is not the purpose of the test don't be too picky
7854      */
7855     color = getPixelColor(device, 320-32, 240);
7856     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7857     color = getPixelColor(device, 320+32, 240);
7858     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7859     color = getPixelColor(device, 320, 240-32);
7860     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7861     color = getPixelColor(device, 320, 240+32);
7862     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7863     color = getPixelColor(device, 320, 240);
7864     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7865     color = getPixelColor(device, 320+32, 240+32);
7866     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7867     color = getPixelColor(device, 320-32, 240+32);
7868     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7869     color = getPixelColor(device, 320+32, 240-32);
7870     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7871     color = getPixelColor(device, 320-32, 240-32);
7872     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7873
7874     for(i = 0; i < 2; i++) {
7875         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7876         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7877         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7878         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7879         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7880         IDirect3DTexture9_Release(texture); /* To destroy it */
7881     }
7882
7883     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7884         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7885         goto cleanup;
7886     }
7887     if(L6V5U5_supported == FALSE) {
7888         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7889         goto cleanup;
7890     }
7891
7892     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7893     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7894     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7895      * would only make this test more complicated
7896      */
7897     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7899     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7901
7902     memset(&locked_rect, 0, sizeof(locked_rect));
7903     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7904     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7905     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7906     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7907     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7908
7909     memset(&locked_rect, 0, sizeof(locked_rect));
7910     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7911     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7912     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7913     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7914     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7915
7916     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7917     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7918     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7919     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7920
7921     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7922     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7923     scale = 2.0;
7924     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7925     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7926     offset = 0.1;
7927     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7928     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7929
7930     hr = IDirect3DDevice9_BeginScene(device);
7931     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7932     if(SUCCEEDED(hr)) {
7933         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7934         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7935         hr = IDirect3DDevice9_EndScene(device);
7936         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7937     }
7938
7939     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7940     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7941     color = getPixelColor(device, 320, 240);
7942     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7943      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7944      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7945      */
7946     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7947
7948     /* Check a result scale factor > 1.0 */
7949     scale = 10;
7950     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7951     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7952     offset = 10;
7953     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7954     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7955
7956     hr = IDirect3DDevice9_BeginScene(device);
7957     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7958     if(SUCCEEDED(hr)) {
7959         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7960         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7961         hr = IDirect3DDevice9_EndScene(device);
7962         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7963     }
7964     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7965     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7966     color = getPixelColor(device, 320, 240);
7967     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7968
7969     /* Check clamping in the scale factor calculation */
7970     scale = 1000;
7971     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7972     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7973     offset = -1;
7974     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7975     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7976
7977     hr = IDirect3DDevice9_BeginScene(device);
7978     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7979     if(SUCCEEDED(hr)) {
7980         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7981         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7982         hr = IDirect3DDevice9_EndScene(device);
7983         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7984     }
7985     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7986     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7987     color = getPixelColor(device, 320, 240);
7988     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7989
7990     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7992     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7994
7995     IDirect3DTexture9_Release(tex1);
7996     IDirect3DTexture9_Release(tex2);
7997
7998 cleanup:
7999     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8000     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8001     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8002     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8003
8004     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8005     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8006     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8007 }
8008
8009 static void stencil_cull_test(IDirect3DDevice9 *device) {
8010     HRESULT hr;
8011     IDirect3DSurface9 *depthstencil = NULL;
8012     D3DSURFACE_DESC desc;
8013     float quad1[] = {
8014         -1.0,   -1.0,   0.1,
8015          0.0,   -1.0,   0.1,
8016         -1.0,    0.0,   0.1,
8017          0.0,    0.0,   0.1,
8018     };
8019     float quad2[] = {
8020          0.0,   -1.0,   0.1,
8021          1.0,   -1.0,   0.1,
8022          0.0,    0.0,   0.1,
8023          1.0,    0.0,   0.1,
8024     };
8025     float quad3[] = {
8026         0.0,    0.0,   0.1,
8027         1.0,    0.0,   0.1,
8028         0.0,    1.0,   0.1,
8029         1.0,    1.0,   0.1,
8030     };
8031     float quad4[] = {
8032         -1.0,    0.0,   0.1,
8033          0.0,    0.0,   0.1,
8034         -1.0,    1.0,   0.1,
8035          0.0,    1.0,   0.1,
8036     };
8037     struct vertex painter[] = {
8038        {-1.0,   -1.0,   0.0,    0x00000000},
8039        { 1.0,   -1.0,   0.0,    0x00000000},
8040        {-1.0,    1.0,   0.0,    0x00000000},
8041        { 1.0,    1.0,   0.0,    0x00000000},
8042     };
8043     WORD indices_cw[]  = {0, 1, 3};
8044     WORD indices_ccw[] = {0, 2, 3};
8045     unsigned int i;
8046     DWORD color;
8047
8048     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8049     if(depthstencil == NULL) {
8050         skip("No depth stencil buffer\n");
8051         return;
8052     }
8053     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8054     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8055     IDirect3DSurface9_Release(depthstencil);
8056     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8057         skip("No 4 or 8 bit stencil surface\n");
8058         return;
8059     }
8060
8061     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8062     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8063     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8064
8065     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8066     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8067     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8068     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8069     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8071     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8072     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8073
8074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8075     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8076     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8077     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8078     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8079     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8080
8081     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8082     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8083     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8084     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8085
8086     /* First pass: Fill the stencil buffer with some values... */
8087     hr = IDirect3DDevice9_BeginScene(device);
8088     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8089     if(SUCCEEDED(hr))
8090     {
8091         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8092         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8093         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8094                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8095         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8096                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8097
8098         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8099         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8100         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8101         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8102         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8103                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8104         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8105                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8106
8107         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8108         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8109         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8110                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8111         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8112                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8113
8114         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8115         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8116         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8117                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8118         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8119                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
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_Present(device, NULL, NULL, NULL, NULL);
8161     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8162
8163     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8164     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8165
8166     color = getPixelColor(device, 160, 420);
8167     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8168     color = getPixelColor(device, 160, 300);
8169     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8170
8171     color = getPixelColor(device, 480, 420);
8172     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8173     color = getPixelColor(device, 480, 300);
8174     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8175
8176     color = getPixelColor(device, 160, 180);
8177     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8178     color = getPixelColor(device, 160, 60);
8179     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8180
8181     color = getPixelColor(device, 480, 180);
8182     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8183     color = getPixelColor(device, 480, 60);
8184     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
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     IDirect3DPixelShader9 *shader, *shader_frac;
8213     IDirect3DSurface9 *surface = NULL, *backbuffer;
8214     const float quad[] = {
8215         -1.0,   -1.0,   0.1,    0.0,    0.0,
8216          1.0,   -1.0,   0.1,    1.0,    0.0,
8217         -1.0,    1.0,   0.1,    0.0,    1.0,
8218          1.0,    1.0,   0.1,    1.0,    1.0,
8219     };
8220     D3DLOCKED_RECT lr;
8221     float constant[4] = {1.0, 0.0, 320, 240};
8222     DWORD *pos;
8223
8224     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8225     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8226     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8227     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8228     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8229     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8230     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8231     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8232     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8233     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8234     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8235     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8236
8237     hr = IDirect3DDevice9_BeginScene(device);
8238     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8239     if(SUCCEEDED(hr)) {
8240         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8241         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8242         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8243         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8244         hr = IDirect3DDevice9_EndScene(device);
8245         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8246     }
8247
8248     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8249     /* This has to be pixel exact */
8250     color = getPixelColor(device, 319, 239);
8251     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8252     color = getPixelColor(device, 320, 239);
8253     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8254     color = getPixelColor(device, 319, 240);
8255     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8256     color = getPixelColor(device, 320, 240);
8257     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8258
8259     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8260                                              &surface, NULL);
8261     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8262     hr = IDirect3DDevice9_BeginScene(device);
8263     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8264     if(SUCCEEDED(hr)) {
8265         constant[2] = 16; constant[3] = 16;
8266         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8267         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8268         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8269         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8270         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8271         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8272         hr = IDirect3DDevice9_EndScene(device);
8273         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8274     }
8275     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8276     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8277
8278     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8279     color = *pos & 0x00ffffff;
8280     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8281     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8282     color = *pos & 0x00ffffff;
8283     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8284     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8285     color = *pos & 0x00ffffff;
8286     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8287     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8288     color = *pos & 0x00ffffff;
8289     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8290
8291     hr = IDirect3DSurface9_UnlockRect(surface);
8292     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8293
8294     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8295      * have full control over the multisampling setting inside this test
8296      */
8297     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8298     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8299     hr = IDirect3DDevice9_BeginScene(device);
8300     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8301     if(SUCCEEDED(hr)) {
8302         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8303         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8304         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8305         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8306         hr = IDirect3DDevice9_EndScene(device);
8307         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8308     }
8309     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8310     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8311
8312     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8313     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8314
8315     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8316     color = *pos & 0x00ffffff;
8317     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8318
8319     hr = IDirect3DSurface9_UnlockRect(surface);
8320     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8321
8322     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8323     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8324     IDirect3DPixelShader9_Release(shader);
8325     IDirect3DPixelShader9_Release(shader_frac);
8326     if(surface) IDirect3DSurface9_Release(surface);
8327     IDirect3DSurface9_Release(backbuffer);
8328 }
8329
8330 static void pointsize_test(IDirect3DDevice9 *device)
8331 {
8332     HRESULT hr;
8333     D3DCAPS9 caps;
8334     D3DMATRIX matrix;
8335     D3DMATRIX identity;
8336     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8337     DWORD color;
8338
8339     const float vertices[] = {
8340         64,     64,     0.1,
8341         128,    64,     0.1,
8342         192,    64,     0.1,
8343         256,    64,     0.1,
8344         320,    64,     0.1,
8345         384,    64,     0.1,
8346         448,    64,     0.1,
8347         512,    64,     0.1,
8348         576,    64,     0.1,
8349     };
8350
8351     /* 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 */
8352     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;
8353     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;
8354     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;
8355     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;
8356
8357     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;
8358     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;
8359     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;
8360     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;
8361
8362     memset(&caps, 0, sizeof(caps));
8363     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8364     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8365     if(caps.MaxPointSize < 32.0) {
8366         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8367         return;
8368     }
8369
8370     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8371     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8372     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8373     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8374     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8375     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8376     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8377     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8378
8379     hr = IDirect3DDevice9_BeginScene(device);
8380     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8381     if(SUCCEEDED(hr)) {
8382         ptsize = 16.0;
8383         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8384         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8385         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8386         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8387
8388         ptsize = 32.0;
8389         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8390         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8391         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8392         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8393
8394         ptsize = 31.5;
8395         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8396         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8397         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8398         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8399
8400         if(caps.MaxPointSize >= 64.0) {
8401             ptsize = 64.0;
8402             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8403             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8404             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8405             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8406
8407             ptsize = 63.75;
8408             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8409             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8410             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8411             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8412         }
8413
8414         ptsize = 1.0;
8415         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8416         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8417         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8418         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8419
8420         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8421         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8422         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemin_orig));
8423         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8424
8425         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8426         ptsize = 16.0;
8427         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8428         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8429         ptsize = 1.0;
8430         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8431         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8433         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8434
8435         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8436          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8437          */
8438         ptsize = 4.0;
8439         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8440         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8441         ptsize = 16.0;
8442         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8443         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8444         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8445         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8446
8447         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8448         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8449
8450         /* pointsize < pointsize_min < pointsize_max?
8451          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8452          */
8453         ptsize = 1.0;
8454         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8455         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8456         ptsize = 16.0;
8457         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8458         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8459         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8460         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8461
8462         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8463         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8464
8465         hr = IDirect3DDevice9_EndScene(device);
8466         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8467     }
8468     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8469     color = getPixelColor(device, 64-9, 64-9);
8470     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8471     color = getPixelColor(device, 64-8, 64-8);
8472     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8473     color = getPixelColor(device, 64-7, 64-7);
8474     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8475     color = getPixelColor(device, 64+7, 64+7);
8476     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8477     color = getPixelColor(device, 64+8, 64+8);
8478     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8479     color = getPixelColor(device, 64+9, 64+9);
8480     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8481
8482     color = getPixelColor(device, 128-17, 64-17);
8483     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8484     color = getPixelColor(device, 128-16, 64-16);
8485     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8486     color = getPixelColor(device, 128-15, 64-15);
8487     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8488     color = getPixelColor(device, 128+15, 64+15);
8489     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8490     color = getPixelColor(device, 128+16, 64+16);
8491     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8492     color = getPixelColor(device, 128+17, 64+17);
8493     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8494
8495     color = getPixelColor(device, 192-17, 64-17);
8496     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8497     color = getPixelColor(device, 192-16, 64-16);
8498     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8499     color = getPixelColor(device, 192-15, 64-15);
8500     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8501     color = getPixelColor(device, 192+15, 64+15);
8502     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8503     color = getPixelColor(device, 192+16, 64+16);
8504     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8505     color = getPixelColor(device, 192+17, 64+17);
8506     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8507
8508     if(caps.MaxPointSize >= 64.0) {
8509         color = getPixelColor(device, 256-33, 64-33);
8510         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8511         color = getPixelColor(device, 256-32, 64-32);
8512         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8513         color = getPixelColor(device, 256-31, 64-31);
8514         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8515         color = getPixelColor(device, 256+31, 64+31);
8516         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8517         color = getPixelColor(device, 256+32, 64+32);
8518         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8519         color = getPixelColor(device, 256+33, 64+33);
8520         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8521
8522         color = getPixelColor(device, 384-33, 64-33);
8523         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8524         color = getPixelColor(device, 384-32, 64-32);
8525         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8526         color = getPixelColor(device, 384-31, 64-31);
8527         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8528         color = getPixelColor(device, 384+31, 64+31);
8529         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8530         color = getPixelColor(device, 384+32, 64+32);
8531         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8532         color = getPixelColor(device, 384+33, 64+33);
8533         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8534     }
8535
8536     color = getPixelColor(device, 320-1, 64-1);
8537     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8538     color = getPixelColor(device, 320-0, 64-0);
8539     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8540     color = getPixelColor(device, 320+1, 64+1);
8541     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8542
8543     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8544     color = getPixelColor(device, 448-4, 64-4);
8545     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8546     color = getPixelColor(device, 448+4, 64+4);
8547     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8548
8549     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8550     color = getPixelColor(device, 512-4, 64-4);
8551     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8552     color = getPixelColor(device, 512+4, 64+4);
8553     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8554
8555     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8556      * Don't be overly picky - just show that the point is bigger than 1 pixel
8557      */
8558     color = getPixelColor(device, 576-4, 64-4);
8559     ok(color == 0x00ffffff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8560     color = getPixelColor(device, 576+4, 64+4);
8561     ok(color == 0x00ffffff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8562
8563     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8564     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8565     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8566     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8567 }
8568
8569 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8570 {
8571     HRESULT hr;
8572     IDirect3DPixelShader9 *ps;
8573     IDirect3DTexture9 *tex1, *tex2;
8574     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8575     D3DCAPS9 caps;
8576     DWORD color;
8577     DWORD shader_code[] = {
8578     0xffff0300,                                                             /* ps_3_0             */
8579     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8580     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8581     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8582     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8583     0x0000ffff                                                              /* END                */
8584     };
8585     float quad[] = {
8586        -1.0,   -1.0,    0.1,
8587         1.0,   -1.0,    0.1,
8588        -1.0,    1.0,    0.1,
8589         1.0,    1.0,    0.1,
8590     };
8591     float texquad[] = {
8592        -1.0,   -1.0,    0.1,    0.0,    0.0,
8593         0.0,   -1.0,    0.1,    1.0,    0.0,
8594        -1.0,    1.0,    0.1,    0.0,    1.0,
8595         0.0,    1.0,    0.1,    1.0,    1.0,
8596
8597         0.0,   -1.0,    0.1,    0.0,    0.0,
8598         1.0,   -1.0,    0.1,    1.0,    0.0,
8599         0.0,    1.0,    0.1,    0.0,    1.0,
8600         1.0,    1.0,    0.1,    1.0,    1.0,
8601     };
8602
8603     memset(&caps, 0, sizeof(caps));
8604     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8605     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8606     if(caps.NumSimultaneousRTs < 2) {
8607         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8608         return;
8609     }
8610
8611     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8612     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8613
8614     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8615     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8616     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8617     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8618     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8619     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8620
8621     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8622     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8623     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8624     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8625     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8626     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8627
8628     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8629     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8630     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8631     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8632     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8633     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8634     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8635     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8636
8637     hr = IDirect3DDevice9_BeginScene(device);
8638     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8639     if(SUCCEEDED(hr)) {
8640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8641         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8642
8643         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8644         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8645         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8646         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8647         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8648         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8649         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8650         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8651
8652         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8653         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8654         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8655         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8656
8657         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8658         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8659         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8660         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8661
8662         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8663         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8664
8665         hr = IDirect3DDevice9_EndScene(device);
8666         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8667     }
8668
8669     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8670     color = getPixelColor(device, 160, 240);
8671     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8672     color = getPixelColor(device, 480, 240);
8673     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8674
8675     IDirect3DPixelShader9_Release(ps);
8676     IDirect3DTexture9_Release(tex1);
8677     IDirect3DTexture9_Release(tex2);
8678     IDirect3DSurface9_Release(surf1);
8679     IDirect3DSurface9_Release(surf2);
8680     IDirect3DSurface9_Release(backbuf);
8681 }
8682
8683 struct formats {
8684     const char *fmtName;
8685     D3DFORMAT textureFormat;
8686     DWORD resultColorBlending;
8687     DWORD resultColorNoBlending;
8688 };
8689
8690 const struct formats test_formats[] = {
8691   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8692   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8693   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8694   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8695   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8696   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8697   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8698   { NULL, 0 }
8699 };
8700
8701 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8702 {
8703     HRESULT hr;
8704     IDirect3DTexture9 *offscreenTexture = NULL;
8705     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8706     IDirect3D9 *d3d = NULL;
8707     DWORD color;
8708     DWORD r0, g0, b0, r1, g1, b1;
8709     int fmt_index;
8710
8711     static const float quad[][5] = {
8712         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8713         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8714         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8715         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8716     };
8717
8718     /* Quad with R=0x10, G=0x20 */
8719     static const struct vertex quad1[] = {
8720         {-1.0f, -1.0f, 0.1f, 0x80102000},
8721         {-1.0f,  1.0f, 0.1f, 0x80102000},
8722         { 1.0f, -1.0f, 0.1f, 0x80102000},
8723         { 1.0f,  1.0f, 0.1f, 0x80102000},
8724     };
8725
8726     /* Quad with R=0x20, G=0x10 */
8727     static const struct vertex quad2[] = {
8728         {-1.0f, -1.0f, 0.1f, 0x80201000},
8729         {-1.0f,  1.0f, 0.1f, 0x80201000},
8730         { 1.0f, -1.0f, 0.1f, 0x80201000},
8731         { 1.0f,  1.0f, 0.1f, 0x80201000},
8732     };
8733
8734     IDirect3DDevice9_GetDirect3D(device, &d3d);
8735
8736     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8737     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8738     if(!backbuffer) {
8739         goto out;
8740     }
8741
8742     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8743     {
8744         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8745         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8746            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8747            continue;
8748         }
8749
8750         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8751         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8752
8753         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8754         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8755         if(!offscreenTexture) {
8756             continue;
8757         }
8758
8759         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8760         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8761         if(!offscreen) {
8762             continue;
8763         }
8764
8765         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8766         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8767
8768         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8769         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8770         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8771         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8772         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8773         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8774         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8775         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8776         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8777         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8778
8779         /* Below we will draw two quads with different colors and try to blend them together.
8780          * The result color is compared with the expected outcome.
8781          */
8782         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8783             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8784             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8785             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8786             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8787
8788             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8789             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8790
8791             /* Draw a quad using color 0x0010200 */
8792             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8793             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8794             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8795             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8796             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8797             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8798
8799             /* Draw a quad using color 0x0020100 */
8800             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8801             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8802             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8803             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8804             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8805             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8806
8807             /* We don't want to blend the result on the backbuffer */
8808             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8809             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8810
8811             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8812             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8813             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8814             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8815             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8816
8817             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8818             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8819
8820             /* This time with the texture */
8821             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8822             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8823
8824             IDirect3DDevice9_EndScene(device);
8825         }
8826         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8827
8828
8829         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8830             /* Compare the color of the center quad with our expectation */
8831             color = getPixelColor(device, 320, 240);
8832             r0 = (color & 0x00ff0000) >> 16;
8833             g0 = (color & 0x0000ff00) >>  8;
8834             b0 = (color & 0x000000ff) >>  0;
8835
8836             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8837             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8838             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8839
8840             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8841                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8842                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8843                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8844         } else {
8845             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8846              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8847              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8848             color = getPixelColor(device, 320, 240);
8849             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);
8850         }
8851
8852         IDirect3DDevice9_SetTexture(device, 0, NULL);
8853         if(offscreenTexture) {
8854             IDirect3DTexture9_Release(offscreenTexture);
8855         }
8856         if(offscreen) {
8857             IDirect3DSurface9_Release(offscreen);
8858         }
8859     }
8860
8861 out:
8862     /* restore things */
8863     if(backbuffer) {
8864         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8865         IDirect3DSurface9_Release(backbuffer);
8866     }
8867 }
8868
8869 static void tssargtemp_test(IDirect3DDevice9 *device)
8870 {
8871     HRESULT hr;
8872     DWORD color;
8873     static const struct vertex quad[] = {
8874         {-1.0,     -1.0,    0.1,    0x00ff0000},
8875         { 1.0,     -1.0,    0.1,    0x00ff0000},
8876         {-1.0,      1.0,    0.1,    0x00ff0000},
8877         { 1.0,      1.0,    0.1,    0x00ff0000}
8878     };
8879     D3DCAPS9 caps;
8880
8881     memset(&caps, 0, sizeof(caps));
8882     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8883     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8884     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8885         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8886         return;
8887     }
8888
8889     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8890     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8891
8892     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8893     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8894     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8895     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8896
8897     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8898     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8899     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8900     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8901     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8902     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8903
8904     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8905     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8906     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8907     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8908     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8909     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8910
8911     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8912     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8913
8914     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8915     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8916     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8917     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8918
8919     hr = IDirect3DDevice9_BeginScene(device);
8920     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8921     if(SUCCEEDED(hr)) {
8922
8923         hr = IDirect3DDevice9_EndScene(device);
8924         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8925         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8926         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8927     }
8928     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8929     color = getPixelColor(device, 320, 240);
8930     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8931
8932     /* Set stage 1 back to default */
8933     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8934     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8935     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8936     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8937     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8938     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8939     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8940     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8941     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8942     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8943 }
8944
8945 struct testdata
8946 {
8947     DWORD idxVertex; /* number of instances in the first stream */
8948     DWORD idxColor; /* number of instances in the second stream */
8949     DWORD idxInstance; /* should be 1 ?? */
8950     DWORD color1; /* color 1 instance */
8951     DWORD color2; /* color 2 instance */
8952     DWORD color3; /* color 3 instance */
8953     DWORD color4; /* color 4 instance */
8954     WORD strVertex; /* specify which stream to use 0-2*/
8955     WORD strColor;
8956     WORD strInstance;
8957 };
8958
8959 static const struct testdata testcases[]=
8960 {
8961     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8962     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8963     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8964     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8965     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8966     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8967     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8968     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8969     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8970     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8971     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8972     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8973     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8974     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8975     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8976 /*
8977     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8978     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8979 */
8980 };
8981
8982 /* Drawing Indexed Geometry with instances*/
8983 static void stream_test(IDirect3DDevice9 *device)
8984 {
8985     IDirect3DVertexBuffer9 *vb = NULL;
8986     IDirect3DVertexBuffer9 *vb2 = NULL;
8987     IDirect3DVertexBuffer9 *vb3 = NULL;
8988     IDirect3DIndexBuffer9 *ib = NULL;
8989     IDirect3DVertexDeclaration9 *pDecl = NULL;
8990     IDirect3DVertexShader9 *shader = NULL;
8991     HRESULT hr;
8992     BYTE *data;
8993     DWORD color;
8994     DWORD ind;
8995     unsigned i;
8996
8997     const DWORD shader_code[] =
8998     {
8999         0xfffe0101,                                     /* vs_1_1 */
9000         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9001         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9002         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9003         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9004         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9005         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9006         0x0000ffff
9007     };
9008
9009     const float quad[][3] =
9010     {
9011         {-0.5f, -0.5f,  1.1f}, /*0 */
9012         {-0.5f,  0.5f,  1.1f}, /*1 */
9013         { 0.5f, -0.5f,  1.1f}, /*2 */
9014         { 0.5f,  0.5f,  1.1f}, /*3 */
9015     };
9016
9017     const float vertcolor[][4] =
9018     {
9019         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9020         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9021         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9022         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9023     };
9024
9025     /* 4 position for 4 instances */
9026     const float instancepos[][3] =
9027     {
9028         {-0.6f,-0.6f, 0.0f},
9029         { 0.6f,-0.6f, 0.0f},
9030         { 0.6f, 0.6f, 0.0f},
9031         {-0.6f, 0.6f, 0.0f},
9032     };
9033
9034     short indices[] = {0, 1, 2, 1, 2, 3};
9035
9036     D3DVERTEXELEMENT9 decl[] =
9037     {
9038         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9039         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9040         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9041         D3DDECL_END()
9042     };
9043
9044     /* set the default value because it isn't done in wine? */
9045     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9046     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9047
9048     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9049     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9050     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9051
9052     /* check wrong cases */
9053     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9054     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9055     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9056     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9057     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9058     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9059     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9060     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9061     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9062     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9063     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9064     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9065     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9066     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9067     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9068     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9069     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9070     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9071     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9072     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9073
9074     /* set the default value back */
9075     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9076     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9077
9078     /* create all VertexBuffers*/
9079     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9080     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9081     if(!vb) {
9082         skip("Failed to create a vertex buffer\n");
9083         return;
9084     }
9085     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9086     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9087     if(!vb2) {
9088         skip("Failed to create a vertex buffer\n");
9089         goto out;
9090     }
9091     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9092     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9093     if(!vb3) {
9094         skip("Failed to create a vertex buffer\n");
9095         goto out;
9096     }
9097
9098     /* create IndexBuffer*/
9099     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9100     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9101     if(!ib) {
9102         skip("Failed to create a index buffer\n");
9103         goto out;
9104     }
9105
9106     /* copy all Buffers (Vertex + Index)*/
9107     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9108     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9109     memcpy(data, quad, sizeof(quad));
9110     hr = IDirect3DVertexBuffer9_Unlock(vb);
9111     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9112     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9113     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9114     memcpy(data, vertcolor, sizeof(vertcolor));
9115     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9116     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9117     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9118     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9119     memcpy(data, instancepos, sizeof(instancepos));
9120     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9121     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9122     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9123     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9124     memcpy(data, indices, sizeof(indices));
9125     hr = IDirect3DIndexBuffer9_Unlock(ib);
9126     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9127
9128     /* create VertexShader */
9129     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9130     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9131     if(!shader) {
9132         skip("Failed to create a vetex shader\n");
9133         goto out;
9134     }
9135
9136     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9137     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9138
9139     hr = IDirect3DDevice9_SetIndices(device, ib);
9140     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9141
9142     /* run all tests */
9143     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9144     {
9145         struct testdata act = testcases[i];
9146         decl[0].Stream = act.strVertex;
9147         decl[1].Stream = act.strColor;
9148         decl[2].Stream = act.strInstance;
9149         /* create VertexDeclarations */
9150         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9151         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9152
9153         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9154         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9155
9156         hr = IDirect3DDevice9_BeginScene(device);
9157         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9158         if(SUCCEEDED(hr))
9159         {
9160             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9161             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9162
9163             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9164             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9165             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9166             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9167
9168             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9169             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9170             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9171             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9172
9173             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9174             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9175             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9176             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9177
9178             /* don't know if this is right (1*3 and 4*1)*/
9179             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9180             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9181             hr = IDirect3DDevice9_EndScene(device);
9182             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9183
9184             /* set all StreamSource && StreamSourceFreq back to default */
9185             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9186             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9187             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9188             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9189             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9190             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9191             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9192             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9193             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9194             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9195             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9196             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9197         }
9198
9199         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9200         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9201
9202         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9203         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9204
9205         color = getPixelColor(device, 160, 360);
9206         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9207         color = getPixelColor(device, 480, 360);
9208         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9209         color = getPixelColor(device, 480, 120);
9210         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9211         color = getPixelColor(device, 160, 120);
9212         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9213     }
9214
9215     hr = IDirect3DDevice9_SetIndices(device, NULL);
9216     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9217
9218 out:
9219     if(vb) IDirect3DVertexBuffer9_Release(vb);
9220     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9221     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9222     if(ib)IDirect3DIndexBuffer9_Release(ib);
9223     if(shader)IDirect3DVertexShader9_Release(shader);
9224 }
9225
9226 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9227     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9228     IDirect3DTexture9 *dsttex = NULL;
9229     HRESULT hr;
9230     DWORD color;
9231     D3DRECT r1 = {0,  0,  50,  50 };
9232     D3DRECT r2 = {50, 0,  100, 50 };
9233     D3DRECT r3 = {50, 50, 100, 100};
9234     D3DRECT r4 = {0,  50,  50, 100};
9235     const float quad[] = {
9236         -1.0,   -1.0,   0.1,    0.0,    0.0,
9237          1.0,   -1.0,   0.1,    1.0,    0.0,
9238         -1.0,    1.0,   0.1,    0.0,    1.0,
9239          1.0,    1.0,   0.1,    1.0,    1.0,
9240     };
9241
9242     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9243     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9244
9245     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9246     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9247     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9248     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9249
9250     if(!src || !dsttex) {
9251         skip("One or more test resources could not be created\n");
9252         goto cleanup;
9253     }
9254
9255     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9256     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9257
9258     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9259     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9260
9261     /* Clear the StretchRect destination for debugging */
9262     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9263     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9264     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9265     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9266
9267     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9268     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9269
9270     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9271     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9272     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9273     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9274     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9275     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9276     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9277     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9278
9279     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9280      * the target -> texture GL blit path
9281      */
9282     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9283     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9284     IDirect3DSurface9_Release(dst);
9285
9286     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9288
9289     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9290     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9291     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9292     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9293     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9294     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9295     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9296     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9297
9298     hr = IDirect3DDevice9_BeginScene(device);
9299     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9300     if(SUCCEEDED(hr)) {
9301         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9302         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9303         hr = IDirect3DDevice9_EndScene(device);
9304         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9305     }
9306
9307     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9308     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9309     color = getPixelColor(device, 160, 360);
9310     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9311     color = getPixelColor(device, 480, 360);
9312     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9313     color = getPixelColor(device, 480, 120);
9314     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9315     color = getPixelColor(device, 160, 120);
9316     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9317
9318     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9319     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9320     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9321     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9322
9323 cleanup:
9324     if(src) IDirect3DSurface9_Release(src);
9325     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9326     if(dsttex) IDirect3DTexture9_Release(dsttex);
9327 }
9328
9329 static void texop_test(IDirect3DDevice9 *device)
9330 {
9331     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9332     IDirect3DTexture9 *texture = NULL;
9333     D3DLOCKED_RECT locked_rect;
9334     D3DCOLOR color;
9335     D3DCAPS9 caps;
9336     HRESULT hr;
9337     unsigned i;
9338
9339     static const struct {
9340         float x, y, z;
9341         float s, t;
9342         D3DCOLOR diffuse;
9343     } quad[] = {
9344         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9345         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9346         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9347         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9348     };
9349
9350     static const D3DVERTEXELEMENT9 decl_elements[] = {
9351         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9352         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9353         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9354         D3DDECL_END()
9355     };
9356
9357     static const struct {
9358         D3DTEXTUREOP op;
9359         const char *name;
9360         DWORD caps_flag;
9361         D3DCOLOR result;
9362     } test_data[] = {
9363         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9364         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9365         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9366         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9367         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9368         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9369         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9370         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9371         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9372         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9373         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9374         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9375         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9376         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9377         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9378         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9379         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9380         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9381         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9382         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9383         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9384         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9385         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9386     };
9387
9388     memset(&caps, 0, sizeof(caps));
9389     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9390     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9391
9392     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9393     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9394     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9395     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9396
9397     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9398     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9399     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9400     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9401     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9402     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9403     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9404     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9405     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9406
9407     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9408     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9409     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9410     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9411     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9412     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9413
9414     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9415     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9416
9417     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9418     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9419     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9420     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9422     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9423
9424     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9425     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9426
9427     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9428     {
9429         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9430         {
9431             skip("tex operation %s not supported\n", test_data[i].name);
9432             continue;
9433         }
9434
9435         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9436         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9437
9438         hr = IDirect3DDevice9_BeginScene(device);
9439         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9440
9441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9442         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9443
9444         hr = IDirect3DDevice9_EndScene(device);
9445         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9446
9447         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9448         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9449
9450         color = getPixelColor(device, 320, 240);
9451         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9452                 test_data[i].name, color, test_data[i].result);
9453     }
9454
9455     if (texture) IDirect3DTexture9_Release(texture);
9456     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9457 }
9458
9459 static void yuv_color_test(IDirect3DDevice9 *device) {
9460     HRESULT hr;
9461     IDirect3DSurface9 *surface = NULL, *target = NULL;
9462     unsigned int fmt, i;
9463     D3DFORMAT format;
9464     const char *fmt_string;
9465     D3DLOCKED_RECT lr;
9466     IDirect3D9 *d3d;
9467     HRESULT color;
9468     DWORD ref_color_left, ref_color_right;
9469
9470     struct {
9471         DWORD in;           /* The input color */
9472         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9473         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9474         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9475         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9476     } test_data[] = {
9477     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9478      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9479      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9480      * that
9481      */
9482       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9483       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9484       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9485       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9486       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9487       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9488       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9489       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9490       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9491       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9492       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9493       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9494       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9495       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9496
9497       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9498       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9499       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9500       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9501     };
9502
9503     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9504     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9505     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9506     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9507
9508     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9509     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9510
9511     for(fmt = 0; fmt < 2; fmt++) {
9512         if(fmt == 0) {
9513             format = D3DFMT_UYVY;
9514             fmt_string = "D3DFMT_UYVY";
9515         } else {
9516             format = D3DFMT_YUY2;
9517             fmt_string = "D3DFMT_YUY2";
9518         }
9519
9520         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9521                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9522                        */
9523         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9524                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9525             skip("%s is not supported\n", fmt_string);
9526             continue;
9527         }
9528
9529         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9530         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9531         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9532
9533         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9534             if(fmt == 0) {
9535                 ref_color_left = test_data[i].uyvy_left;
9536                 ref_color_right = test_data[i].uyvy_right;
9537             } else {
9538                 ref_color_left = test_data[i].yuy2_left;
9539                 ref_color_right = test_data[i].yuy2_right;
9540             }
9541
9542             memset(&lr, 0, sizeof(lr));
9543             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9544             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9545             *((DWORD *) lr.pBits) = test_data[i].in;
9546             hr = IDirect3DSurface9_UnlockRect(surface);
9547             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9548
9549             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9550             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9551             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9552             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9553             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9554             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9555
9556             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9557              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9558              * want to add tests for the filtered pixels as well.
9559              *
9560              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9561              * differently, so we need a max diff of 16
9562              */
9563             color = getPixelColor(device, 40, 240);
9564             ok(color_match(color, ref_color_left, 16),
9565                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9566                test_data[i].in, color, ref_color_left, fmt_string);
9567             color = getPixelColor(device, 600, 240);
9568             ok(color_match(color, ref_color_right, 16),
9569                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9570                test_data[i].in, color, ref_color_left, fmt_string);
9571         }
9572         IDirect3DSurface9_Release(surface);
9573     }
9574     IDirect3DSurface9_Release(target);
9575     IDirect3D9_Release(d3d);
9576 }
9577
9578 static void texop_range_test(IDirect3DDevice9 *device)
9579 {
9580     static const struct {
9581         float x, y, z;
9582         D3DCOLOR diffuse;
9583     } quad[] = {
9584         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9585         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9586         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9587         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9588     };
9589     HRESULT hr;
9590     IDirect3DTexture9 *texture;
9591     D3DLOCKED_RECT locked_rect;
9592     D3DCAPS9 caps;
9593     DWORD color;
9594
9595     /* We need ADD and SUBTRACT operations */
9596     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9597     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9598     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9599         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9600     }
9601     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9602         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9603     }
9604
9605     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9606     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9607     /* Stage 1: result = diffuse(=1.0) + diffuse
9608      * stage 2: result = result - tfactor(= 0.5)
9609      */
9610     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9611     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9612     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9613     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9614     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9615     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9616     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9617     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9618     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9619     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9620     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9621     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9622     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9623     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9624
9625     hr = IDirect3DDevice9_BeginScene(device);
9626     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9627     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9628     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9629     hr = IDirect3DDevice9_EndScene(device);
9630     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9631     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9632     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9633
9634     color = getPixelColor(device, 320, 240);
9635     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9636        color);
9637
9638     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9639     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9640     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9641     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9642     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9643     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9644     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9645     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9646     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9647
9648     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9649      * stage 2: result = result + diffuse(1.0)
9650      */
9651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9652     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9653     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9654     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9655     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9656     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9657     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9658     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9659     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9660     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9661     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9662     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9663     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9664     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9665
9666     hr = IDirect3DDevice9_BeginScene(device);
9667     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9668     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9669     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9670     hr = IDirect3DDevice9_EndScene(device);
9671     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9672     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9673     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9674
9675     color = getPixelColor(device, 320, 240);
9676     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9677        color);
9678
9679     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9680     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9681     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9682     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9683     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9684     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9685     IDirect3DTexture9_Release(texture);
9686 }
9687
9688 static void alphareplicate_test(IDirect3DDevice9 *device) {
9689     struct vertex quad[] = {
9690         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9691         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9692         { -1.0,     1.0,    0.1,    0x80ff00ff },
9693         {  1.0,     1.0,    0.1,    0x80ff00ff },
9694     };
9695     HRESULT hr;
9696     DWORD color;
9697
9698     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9699     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9700
9701     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9702     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9703
9704     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9705     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9706     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9707     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9708
9709     hr = IDirect3DDevice9_BeginScene(device);
9710     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9711     if(SUCCEEDED(hr)) {
9712         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9713         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9714         hr = IDirect3DDevice9_EndScene(device);
9715         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9716     }
9717
9718     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9719     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9720
9721     color = getPixelColor(device, 320, 240);
9722     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9723        color);
9724
9725     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9726     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9727
9728 }
9729
9730 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9731     HRESULT hr;
9732     D3DCAPS9 caps;
9733     DWORD color;
9734     struct vertex quad[] = {
9735         { -1.0,    -1.0,    0.1,    0x408080c0 },
9736         {  1.0,    -1.0,    0.1,    0x408080c0 },
9737         { -1.0,     1.0,    0.1,    0x408080c0 },
9738         {  1.0,     1.0,    0.1,    0x408080c0 },
9739     };
9740
9741     memset(&caps, 0, sizeof(caps));
9742     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9743     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9744     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9745         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9746         return;
9747     }
9748
9749     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9750     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9751
9752     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9753     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9754
9755     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9756      * mov r0.a, diffuse.a
9757      * mov r0, r0.a
9758      *
9759      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9760      * 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
9761      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9762      */
9763     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9764     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9765     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9766     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9767     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9768     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9769     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9770     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9771     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9772     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9773     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9774     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9775     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9776     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9777     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9778     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9780     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9781
9782     hr = IDirect3DDevice9_BeginScene(device);
9783     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9784     if(SUCCEEDED(hr)) {
9785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9786         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9787         hr = IDirect3DDevice9_EndScene(device);
9788         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9789     }
9790
9791     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9792     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9793
9794     color = getPixelColor(device, 320, 240);
9795     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9796        color);
9797
9798     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9799     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9800     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9801     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9802     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9803     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9804 }
9805
9806 static void zwriteenable_test(IDirect3DDevice9 *device) {
9807     HRESULT hr;
9808     DWORD color;
9809     struct vertex quad1[] = {
9810         { -1.0,  -1.0,  0.1,    0x00ff0000},
9811         { -1.0,   1.0,  0.1,    0x00ff0000},
9812         {  1.0,  -1.0,  0.1,    0x00ff0000},
9813         {  1.0,   1.0,  0.1,    0x00ff0000},
9814     };
9815     struct vertex quad2[] = {
9816         { -1.0,  -1.0,  0.9,    0x0000ff00},
9817         { -1.0,   1.0,  0.9,    0x0000ff00},
9818         {  1.0,  -1.0,  0.9,    0x0000ff00},
9819         {  1.0,   1.0,  0.9,    0x0000ff00},
9820     };
9821
9822     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9823     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9824
9825     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9826     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9827     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9828     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9829     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9830     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9831     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9832     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9833
9834     hr = IDirect3DDevice9_BeginScene(device);
9835     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9836     if(SUCCEEDED(hr)) {
9837         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9838          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9839          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9840          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9841          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9842          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9843          */
9844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9845         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9846         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9847         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9848         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9849         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9850
9851         hr = IDirect3DDevice9_EndScene(device);
9852         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9853     }
9854
9855     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9856     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9857     color = getPixelColor(device, 320, 240);
9858     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9859        color);
9860
9861     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9862     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9863 }
9864
9865 START_TEST(visual)
9866 {
9867     IDirect3DDevice9 *device_ptr;
9868     D3DCAPS9 caps;
9869     HRESULT hr;
9870     DWORD color;
9871
9872     d3d9_handle = LoadLibraryA("d3d9.dll");
9873     if (!d3d9_handle)
9874     {
9875         skip("Could not load d3d9.dll\n");
9876         return;
9877     }
9878
9879     device_ptr = init_d3d9();
9880     if (!device_ptr)
9881     {
9882         skip("Creating the device failed\n");
9883         return;
9884     }
9885
9886     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9887
9888     /* Check for the reliability of the returned data */
9889     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9890     if(FAILED(hr))
9891     {
9892         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9893         goto cleanup;
9894     }
9895     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9896
9897     color = getPixelColor(device_ptr, 1, 1);
9898     if(color !=0x00ff0000)
9899     {
9900         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9901         goto cleanup;
9902     }
9903
9904     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9905     if(FAILED(hr))
9906     {
9907         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9908         goto cleanup;
9909     }
9910     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9911
9912     color = getPixelColor(device_ptr, 639, 479);
9913     if(color != 0x0000ddee)
9914     {
9915         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9916         goto cleanup;
9917     }
9918
9919     /* Now execute the real tests */
9920     stretchrect_test(device_ptr);
9921     lighting_test(device_ptr);
9922     clear_test(device_ptr);
9923     fog_test(device_ptr);
9924     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9925     {
9926         test_cube_wrap(device_ptr);
9927     } else {
9928         skip("No cube texture support\n");
9929     }
9930     z_range_test(device_ptr);
9931     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9932     {
9933         maxmip_test(device_ptr);
9934     }
9935     else
9936     {
9937         skip("No mipmap support\n");
9938     }
9939     offscreen_test(device_ptr);
9940     alpha_test(device_ptr);
9941     shademode_test(device_ptr);
9942     srgbtexture_test(device_ptr);
9943     release_buffer_test(device_ptr);
9944     float_texture_test(device_ptr);
9945     g16r16_texture_test(device_ptr);
9946     pixelshader_blending_test(device_ptr);
9947     texture_transform_flags_test(device_ptr);
9948     autogen_mipmap_test(device_ptr);
9949     fixed_function_decl_test(device_ptr);
9950     conditional_np2_repeat_test(device_ptr);
9951     fixed_function_bumpmap_test(device_ptr);
9952     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9953         stencil_cull_test(device_ptr);
9954     } else {
9955         skip("No two sided stencil support\n");
9956     }
9957     pointsize_test(device_ptr);
9958     tssargtemp_test(device_ptr);
9959     np2_stretch_rect_test(device_ptr);
9960     yuv_color_test(device_ptr);
9961     zwriteenable_test(device_ptr);
9962
9963     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9964     {
9965         test_constant_clamp_vs(device_ptr);
9966         test_compare_instructions(device_ptr);
9967     }
9968     else skip("No vs_1_1 support\n");
9969
9970     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9971     {
9972         test_mova(device_ptr);
9973         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9974             test_vshader_input(device_ptr);
9975             test_vshader_float16(device_ptr);
9976             stream_test(device_ptr);
9977         } else {
9978             skip("No vs_3_0 support\n");
9979         }
9980     }
9981     else skip("No vs_2_0 support\n");
9982
9983     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9984     {
9985         fog_with_shader_test(device_ptr);
9986         fog_srgbwrite_test(device_ptr);
9987     }
9988     else skip("No vs_1_1 and ps_1_1 support\n");
9989
9990     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9991     {
9992         texbem_test(device_ptr);
9993         texdepth_test(device_ptr);
9994         texkill_test(device_ptr);
9995         x8l8v8u8_test(device_ptr);
9996         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9997             constant_clamp_ps_test(device_ptr);
9998             cnd_test(device_ptr);
9999             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10000                 dp2add_ps_test(device_ptr);
10001                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10002                     nested_loop_test(device_ptr);
10003                     fixed_function_varying_test(device_ptr);
10004                     vFace_register_test(device_ptr);
10005                     vpos_register_test(device_ptr);
10006                     multiple_rendertargets_test(device_ptr);
10007                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10008                         vshader_version_varying_test(device_ptr);
10009                         pshader_version_varying_test(device_ptr);
10010                     } else {
10011                         skip("No vs_3_0 support\n");
10012                     }
10013                 } else {
10014                     skip("No ps_3_0 support\n");
10015                 }
10016             } else {
10017                 skip("No ps_2_0 support\n");
10018             }
10019         }
10020     }
10021     else skip("No ps_1_1 support\n");
10022
10023     texop_test(device_ptr);
10024     texop_range_test(device_ptr);
10025     alphareplicate_test(device_ptr);
10026     dp3_alpha_test(device_ptr);
10027
10028 cleanup:
10029     if(device_ptr) {
10030         ULONG ref;
10031
10032         D3DPRESENT_PARAMETERS present_parameters;
10033         IDirect3DSwapChain9 *swapchain;
10034         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10035         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10036         IDirect3DSwapChain9_Release(swapchain);
10037         ref = IDirect3DDevice9_Release(device_ptr);
10038         DestroyWindow(present_parameters.hDeviceWindow);
10039         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10040     }
10041 }