d3d9: Test viewports that are bigger than the surface.
[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     ok(identifier.Description[0] != '\0', "Empty driver description\n");
186     trace("Device name string: \"%s\"\n", identifier.DeviceName);
187     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
188     trace("Driver version %d.%d.%d.%d\n",
189           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
190           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
191
192     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
193     if(FAILED(hr)) {
194         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
195         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196         if(FAILED(hr)) {
197             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
198         }
199     }
200     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
201
202     return device_ptr;
203 }
204
205 struct vertex
206 {
207     float x, y, z;
208     DWORD diffuse;
209 };
210
211 struct tvertex
212 {
213     float x, y, z, rhw;
214     DWORD diffuse;
215 };
216
217 struct nvertex
218 {
219     float x, y, z;
220     float nx, ny, nz;
221     DWORD diffuse;
222 };
223
224 static void lighting_test(IDirect3DDevice9 *device)
225 {
226     HRESULT hr;
227     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
228     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
229     DWORD color;
230     D3DMATERIAL9 material, old_material;
231     DWORD cop, carg;
232
233     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
234                       0.0f, 1.0f, 0.0f, 0.0f,
235                       0.0f, 0.0f, 1.0f, 0.0f,
236                       0.0f, 0.0f, 0.0f, 1.0f };
237
238     struct vertex unlitquad[] =
239     {
240         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
241         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
242         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
243         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
244     };
245     struct vertex litquad[] =
246     {
247         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
248         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
249         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
250         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
251     };
252     struct nvertex unlitnquad[] =
253     {
254         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
255         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
256         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
257         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
258     };
259     struct nvertex litnquad[] =
260     {
261         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
262         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
263         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
264         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
265     };
266     WORD Indices[] = {0, 1, 2, 2, 3, 0};
267
268     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
269     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
270
271     /* Setup some states that may cause issues */
272     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
275     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
277     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
278     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
279     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
281     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
296
297     hr = IDirect3DDevice9_SetFVF(device, 0);
298     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
299
300     hr = IDirect3DDevice9_SetFVF(device, fvf);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
302
303     hr = IDirect3DDevice9_BeginScene(device);
304     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
305     if(hr == D3D_OK)
306     {
307         /* No lights are defined... That means, lit vertices should be entirely black */
308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
310         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
311                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
312         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
313
314         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
315         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
317                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
318         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
319
320         hr = IDirect3DDevice9_SetFVF(device, nfvf);
321         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
322
323         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
324         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
327         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
328
329         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
330         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
331         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
332                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
333         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
334
335         IDirect3DDevice9_EndScene(device);
336         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
337     }
338
339     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
340
341     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
342     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
343     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
344     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
345     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
346     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
347     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
348     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
349
350     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
351     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
352     memset(&material, 0, sizeof(material));
353     material.Diffuse.r = 0.0;
354     material.Diffuse.g = 0.0;
355     material.Diffuse.b = 0.0;
356     material.Diffuse.a = 1.0;
357     material.Ambient.r = 0.0;
358     material.Ambient.g = 0.0;
359     material.Ambient.b = 0.0;
360     material.Ambient.a = 0.0;
361     material.Specular.r = 0.0;
362     material.Specular.g = 0.0;
363     material.Specular.b = 0.0;
364     material.Specular.a = 0.0;
365     material.Emissive.r = 0.0;
366     material.Emissive.g = 0.0;
367     material.Emissive.b = 0.0;
368     material.Emissive.a = 0.0;
369     material.Power = 0.0;
370     IDirect3DDevice9_SetMaterial(device, &material);
371     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
372
373     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
374     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
375     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
376     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
377
378     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
379     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
381     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
382     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
383     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
384     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
386
387     hr = IDirect3DDevice9_BeginScene(device);
388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
389     if(SUCCEEDED(hr)) {
390         struct vertex lighting_test[] = {
391             {-1.0,   -1.0,   0.1,    0x8000ff00},
392             { 1.0,   -1.0,   0.1,    0x80000000},
393             {-1.0,    1.0,   0.1,    0x8000ff00},
394             { 1.0,    1.0,   0.1,    0x80000000}
395         };
396         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
397         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
398         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
399         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
400
401         hr = IDirect3DDevice9_EndScene(device);
402         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
403     }
404
405     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
406     color = getPixelColor(device, 320, 240);
407     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
408
409     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
414     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
417     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
418     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
419     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
421 }
422
423 static void clear_test(IDirect3DDevice9 *device)
424 {
425     /* Tests the correctness of clearing parameters */
426     HRESULT hr;
427     D3DRECT rect[2];
428     D3DRECT rect_negneg;
429     DWORD color;
430     D3DVIEWPORT9 old_vp, vp;
431     RECT scissor;
432     DWORD oldColorWrite;
433     BOOL invalid_clear_failed = FALSE;
434
435     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
436     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
437
438     /* Positive x, negative y */
439     rect[0].x1 = 0;
440     rect[0].y1 = 480;
441     rect[0].x2 = 320;
442     rect[0].y2 = 240;
443
444     /* Positive x, positive y */
445     rect[1].x1 = 0;
446     rect[1].y1 = 0;
447     rect[1].x2 = 320;
448     rect[1].y2 = 240;
449     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
450      * returns D3D_OK, but ignores the rectangle silently
451      */
452     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
453     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
454     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
455
456     /* negative x, negative y */
457     rect_negneg.x1 = 640;
458     rect_negneg.y1 = 240;
459     rect_negneg.x2 = 320;
460     rect_negneg.y2 = 0;
461     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
462     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
463     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
464
465     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
466
467     color = getPixelColor(device, 160, 360); /* lower left quad */
468     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
469     color = getPixelColor(device, 160, 120); /* upper left quad */
470     if(invalid_clear_failed) {
471         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
472         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
473     } else {
474         /* If the negative rectangle was dropped silently, the correct ones are cleared */
475         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
476     }
477     color = getPixelColor(device, 480, 360); /* lower right quad  */
478     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
479     color = getPixelColor(device, 480, 120); /* upper right quad */
480     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
481
482     /* Test how the viewport affects clears */
483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
484     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
485     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
486     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
487
488     vp.X = 160;
489     vp.Y = 120;
490     vp.Width = 160;
491     vp.Height = 120;
492     vp.MinZ = 0.0;
493     vp.MaxZ = 1.0;
494     hr = IDirect3DDevice9_SetViewport(device, &vp);
495     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
496     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
497     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
498
499     vp.X = 320;
500     vp.Y = 240;
501     vp.Width = 320;
502     vp.Height = 240;
503     vp.MinZ = 0.0;
504     vp.MaxZ = 1.0;
505     hr = IDirect3DDevice9_SetViewport(device, &vp);
506     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
507     rect[0].x1 = 160;
508     rect[0].y1 = 120;
509     rect[0].x2 = 480;
510     rect[0].y2 = 360;
511     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
512     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
513
514     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
515     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
516
517     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
518     color = getPixelColor(device, 158, 118);
519     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
520     color = getPixelColor(device, 162, 118);
521     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
522     color = getPixelColor(device, 158, 122);
523     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
524     color = getPixelColor(device, 162, 122);
525     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
526
527     color = getPixelColor(device, 318, 238);
528     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
529     color = getPixelColor(device, 322, 238);
530     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
531     color = getPixelColor(device, 318, 242);
532     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
533     color = getPixelColor(device, 322, 242);
534     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
535
536     color = getPixelColor(device, 478, 358);
537     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
538     color = getPixelColor(device, 482, 358);
539     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
540     color = getPixelColor(device, 478, 362);
541     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
542     color = getPixelColor(device, 482, 362);
543     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
544
545     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
546     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
547
548     scissor.left = 160;
549     scissor.right = 480;
550     scissor.top = 120;
551     scissor.bottom = 360;
552     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
553     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
555     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
556
557     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
558     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
561
562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
563     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
564
565     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566     color = getPixelColor(device, 158, 118);
567     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
568     color = getPixelColor(device, 162, 118);
569     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
570     color = getPixelColor(device, 158, 122);
571     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
572     color = getPixelColor(device, 162, 122);
573     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
574
575     color = getPixelColor(device, 158, 358);
576     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
577     color = getPixelColor(device, 162, 358);
578     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
579     color = getPixelColor(device, 158, 358);
580     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
581     color = getPixelColor(device, 162, 362);
582     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
583
584     color = getPixelColor(device, 478, 118);
585     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
586     color = getPixelColor(device, 478, 122);
587     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
588     color = getPixelColor(device, 482, 122);
589     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
590     color = getPixelColor(device, 482, 358);
591     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
592
593     color = getPixelColor(device, 478, 358);
594     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
595     color = getPixelColor(device, 478, 362);
596     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
597     color = getPixelColor(device, 482, 358);
598     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
599     color = getPixelColor(device, 482, 362);
600     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
601
602     color = getPixelColor(device, 318, 238);
603     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
604     color = getPixelColor(device, 318, 242);
605     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
606     color = getPixelColor(device, 322, 238);
607     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
608     color = getPixelColor(device, 322, 242);
609     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
610
611     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
612     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
613     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
614     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
615
616     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
617     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
618
619     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
620     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
621
622     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
623
624     /* Colorwriteenable does not affect the clear */
625     color = getPixelColor(device, 320, 240);
626     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
627 }
628
629 typedef struct {
630     float in[4];
631     DWORD out;
632 } test_data_t;
633
634 /*
635  *  c7      mova    ARGB            mov     ARGB
636  * -2.4     -2      0x00ffff00      -3      0x00ff0000
637  * -1.6     -2      0x00ffff00      -2      0x00ffff00
638  * -0.4      0      0x0000ffff      -1      0x0000ff00
639  *  0.4      0      0x0000ffff       0      0x0000ffff
640  *  1.6      2      0x00ff00ff       1      0x000000ff
641  *  2.4      2      0x00ff00ff       2      0x00ff00ff
642  */
643 static void test_mova(IDirect3DDevice9 *device)
644 {
645     static const DWORD mova_test[] = {
646         0xfffe0200,                                                             /* vs_2_0                       */
647         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
648         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
649         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
650         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
651         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
652         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
653         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
654         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
655         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
656         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
657         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
658         0x0000ffff                                                              /* END                          */
659     };
660     static const DWORD mov_test[] = {
661         0xfffe0101,                                                             /* vs_1_1                       */
662         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
663         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
664         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
665         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
666         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
667         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
668         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
669         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
670         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
671         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
672         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
673         0x0000ffff                                                              /* END                          */
674     };
675
676     static const test_data_t test_data[2][6] = {
677         {
678             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
679             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
680             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
681             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
682             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
683             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
684         },
685         {
686             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
687             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
688             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
689             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
690             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
691             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
692         }
693     };
694
695     static const float quad[][3] = {
696         {-1.0f, -1.0f, 0.0f},
697         {-1.0f,  1.0f, 0.0f},
698         { 1.0f, -1.0f, 0.0f},
699         { 1.0f,  1.0f, 0.0f},
700     };
701
702     static const D3DVERTEXELEMENT9 decl_elements[] = {
703         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
704         D3DDECL_END()
705     };
706
707     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
708     IDirect3DVertexShader9 *mova_shader = NULL;
709     IDirect3DVertexShader9 *mov_shader = NULL;
710     HRESULT hr;
711     UINT i, j;
712
713     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
714     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
716     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
717     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
718     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
719     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
720     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
721
722     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
723     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
724     for(j = 0; j < 2; ++j)
725     {
726         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
727         {
728             DWORD color;
729
730             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
731             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
732
733             hr = IDirect3DDevice9_BeginScene(device);
734             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
735
736             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
737             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
738
739             hr = IDirect3DDevice9_EndScene(device);
740             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
741
742             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
743             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
744
745             color = getPixelColor(device, 320, 240);
746             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
747                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
748
749             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
750             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
751         }
752         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
753         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
754     }
755
756     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
757     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
758
759     IDirect3DVertexDeclaration9_Release(vertex_declaration);
760     IDirect3DVertexShader9_Release(mova_shader);
761     IDirect3DVertexShader9_Release(mov_shader);
762 }
763
764 struct sVertex {
765     float x, y, z;
766     DWORD diffuse;
767     DWORD specular;
768 };
769
770 struct sVertexT {
771     float x, y, z, rhw;
772     DWORD diffuse;
773     DWORD specular;
774 };
775
776 static void fog_test(IDirect3DDevice9 *device)
777 {
778     HRESULT hr;
779     D3DCOLOR color;
780     float start = 0.0f, end = 1.0f;
781     D3DCAPS9 caps;
782     int i;
783
784     /* Gets full z based fog with linear fog, no fog with specular color */
785     struct sVertex unstransformed_1[] = {
786         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
787         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
788         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
789         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
790     };
791     /* Ok, I am too lazy to deal with transform matrices */
792     struct sVertex unstransformed_2[] = {
793         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
794         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
795         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
796         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
797     };
798     /* Untransformed ones. Give them a different diffuse color to make the test look
799      * nicer. It also makes making sure that they are drawn correctly easier.
800      */
801     struct sVertexT transformed_1[] = {
802         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
803         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
804         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
805         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
806     };
807     struct sVertexT transformed_2[] = {
808         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
809         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
810         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
811         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
812     };
813     struct vertex rev_fog_quads[] = {
814        {-1.0,   -1.0,   0.1,    0x000000ff},
815        {-1.0,    0.0,   0.1,    0x000000ff},
816        { 0.0,    0.0,   0.1,    0x000000ff},
817        { 0.0,   -1.0,   0.1,    0x000000ff},
818
819        { 0.0,   -1.0,   0.9,    0x000000ff},
820        { 0.0,    0.0,   0.9,    0x000000ff},
821        { 1.0,    0.0,   0.9,    0x000000ff},
822        { 1.0,   -1.0,   0.9,    0x000000ff},
823
824        { 0.0,    0.0,   0.4,    0x000000ff},
825        { 0.0,    1.0,   0.4,    0x000000ff},
826        { 1.0,    1.0,   0.4,    0x000000ff},
827        { 1.0,    0.0,   0.4,    0x000000ff},
828
829        {-1.0,    0.0,   0.7,    0x000000ff},
830        {-1.0,    1.0,   0.7,    0x000000ff},
831        { 0.0,    1.0,   0.7,    0x000000ff},
832        { 0.0,    0.0,   0.7,    0x000000ff},
833     };
834     WORD Indices[] = {0, 1, 2, 2, 3, 0};
835
836     memset(&caps, 0, sizeof(caps));
837     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
838     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
839     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
840     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
841
842     /* Setup initial states: No lighting, fog on, fog color */
843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
844     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
845     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
846     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
847     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
848     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
849
850     /* First test: Both table fog and vertex fog off */
851     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
852     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
853     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
854     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
855
856     /* Start = 0, end = 1. Should be default, but set them */
857     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
858     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
859     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
860     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
861
862     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
863     {
864         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
865         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
866         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
867         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
868                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
869                                                      sizeof(unstransformed_1[0]));
870         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
871
872         /* That makes it use the Z value */
873         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
874         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
875         /* Untransformed, vertex fog != none (or table fog != none):
876          * Use the Z value as input into the equation
877          */
878         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
879                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
880                                                      sizeof(unstransformed_1[0]));
881         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
882
883         /* transformed verts */
884         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
885         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
886         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
887         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
888                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
889                                                      sizeof(transformed_1[0]));
890         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
891
892         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
893         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
894         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
895          * equation
896          */
897         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
898                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
899                                                      sizeof(transformed_2[0]));
900
901         hr = IDirect3DDevice9_EndScene(device);
902         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
903     }
904     else
905     {
906         ok(FALSE, "BeginScene failed\n");
907     }
908
909     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
910     color = getPixelColor(device, 160, 360);
911     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
912     color = getPixelColor(device, 160, 120);
913     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
914     color = getPixelColor(device, 480, 120);
915     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
916     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
917     {
918         color = getPixelColor(device, 480, 360);
919         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
920     }
921     else
922     {
923         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
924          * The settings above result in no fogging with vertex fog
925          */
926         color = getPixelColor(device, 480, 120);
927         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
928         trace("Info: Table fog not supported by this device\n");
929     }
930
931     /* Now test the special case fogstart == fogend */
932     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
933     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
934
935     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
936     {
937         start = 512;
938         end = 512;
939         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
940         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
941         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
942         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
943
944         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
945         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
946         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
947         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
948         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
949         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
950
951         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
952          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
953          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
954          * The third transformed quad remains unfogged because the fogcoords are read from the specular
955          * color and has fixed fogstart and fogend.
956          */
957         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
959                 sizeof(unstransformed_1[0]));
960         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
961         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
962                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
963                 sizeof(unstransformed_1[0]));
964         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
965
966         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
967         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
968         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
969         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
970                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
971                 sizeof(transformed_1[0]));
972         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
973
974         hr = IDirect3DDevice9_EndScene(device);
975         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
976     }
977     else
978     {
979         ok(FALSE, "BeginScene failed\n");
980     }
981     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
982     color = getPixelColor(device, 160, 360);
983     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
984     color = getPixelColor(device, 160, 120);
985     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
986     color = getPixelColor(device, 480, 120);
987     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
988
989     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
990      * but without shaders it seems to work everywhere
991      */
992     end = 0.2;
993     start = 0.8;
994     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
995     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
997     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
998     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
999     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1000
1001     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1002      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1003      * so skip this for now
1004      */
1005     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1006         const char *mode = (i ? "table" : "vertex");
1007         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1008         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1009         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1010         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1011         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1012         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1013         hr = IDirect3DDevice9_BeginScene(device);
1014         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1015         if(SUCCEEDED(hr)) {
1016             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1017                                 4,  5,  6,  6,  7, 4,
1018                                 8,  9, 10, 10, 11, 8,
1019                             12, 13, 14, 14, 15, 12};
1020
1021             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1022                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1023                     sizeof(rev_fog_quads[0]));
1024
1025             hr = IDirect3DDevice9_EndScene(device);
1026             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1027         }
1028         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1029         color = getPixelColor(device, 160, 360);
1030         ok(color_match(color, 0x0000ff00, 1),
1031                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1032
1033         color = getPixelColor(device, 160, 120);
1034         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1035                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1036
1037         color = getPixelColor(device, 480, 120);
1038         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1039                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1040
1041         color = getPixelColor(device, 480, 360);
1042         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1043
1044         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1045             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1046             break;
1047         }
1048     }
1049     /* Turn off the fog master switch to avoid confusing other tests */
1050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1051     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1052     start = 0.0;
1053     end = 1.0;
1054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1055     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1057     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1059     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1061     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1062 }
1063
1064 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1065  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1066  * regardless of the actual addressing mode set. */
1067 static void test_cube_wrap(IDirect3DDevice9 *device)
1068 {
1069     static const float quad[][6] = {
1070         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
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     };
1075
1076     static const D3DVERTEXELEMENT9 decl_elements[] = {
1077         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1078         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1079         D3DDECL_END()
1080     };
1081
1082     static const struct {
1083         D3DTEXTUREADDRESS mode;
1084         const char *name;
1085     } address_modes[] = {
1086         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1087         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1088         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1089         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1090         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1091     };
1092
1093     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1094     IDirect3DCubeTexture9 *texture = NULL;
1095     IDirect3DSurface9 *surface = NULL;
1096     D3DLOCKED_RECT locked_rect;
1097     HRESULT hr;
1098     UINT x;
1099     INT y, face;
1100
1101     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1102     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1103     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1104     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1105
1106     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1107             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1108     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1109
1110     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1111     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1112
1113     for (y = 0; y < 128; ++y)
1114     {
1115         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1116         for (x = 0; x < 64; ++x)
1117         {
1118             *ptr++ = 0xffff0000;
1119         }
1120         for (x = 64; x < 128; ++x)
1121         {
1122             *ptr++ = 0xff0000ff;
1123         }
1124     }
1125
1126     hr = IDirect3DSurface9_UnlockRect(surface);
1127     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1128
1129     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1130             D3DPOOL_DEFAULT, &texture, NULL);
1131     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1132
1133     /* Create cube faces */
1134     for (face = 0; face < 6; ++face)
1135     {
1136         IDirect3DSurface9 *face_surface = NULL;
1137
1138         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1139         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1140
1141         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1142         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1143
1144         IDirect3DSurface9_Release(face_surface);
1145     }
1146
1147     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1148     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1149
1150     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1151     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1152     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1153     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1154     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1155     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1156
1157     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1158     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1159
1160     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1161     {
1162         DWORD color;
1163
1164         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1165         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1166         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1167         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1168
1169         hr = IDirect3DDevice9_BeginScene(device);
1170         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1171
1172         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1173         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1174
1175         hr = IDirect3DDevice9_EndScene(device);
1176         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1177
1178         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1179         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1180
1181         /* Due to the nature of this test, we sample essentially at the edge
1182          * between two faces. Because of this it's undefined from which face
1183          * the driver will sample. Fortunately that's not important for this
1184          * test, since all we care about is that it doesn't sample from the
1185          * other side of the surface or from the border. */
1186         color = getPixelColor(device, 320, 240);
1187         ok(color == 0x00ff0000 || color == 0x000000ff,
1188                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1189                 color, address_modes[x].name);
1190
1191         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1192         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1193     }
1194
1195     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1196     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1197
1198     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1199     IDirect3DCubeTexture9_Release(texture);
1200     IDirect3DSurface9_Release(surface);
1201 }
1202
1203 static void offscreen_test(IDirect3DDevice9 *device)
1204 {
1205     HRESULT hr;
1206     IDirect3DTexture9 *offscreenTexture = NULL;
1207     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1208     DWORD color;
1209
1210     static const float quad[][5] = {
1211         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1212         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1213         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1214         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1215     };
1216
1217     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1218     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1219
1220     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1221     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1222     if(!offscreenTexture) {
1223         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1224         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1225         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1226         if(!offscreenTexture) {
1227             skip("Cannot create an offscreen render target\n");
1228             goto out;
1229         }
1230     }
1231
1232     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1233     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1234     if(!backbuffer) {
1235         goto out;
1236     }
1237
1238     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1239     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1240     if(!offscreen) {
1241         goto out;
1242     }
1243
1244     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1245     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1246
1247     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1248     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1249     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1250     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1251     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1252     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1253     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1254     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1255     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1256     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1257
1258     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1259         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1260         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1261         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1262         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1263
1264         /* Draw without textures - Should result in a white quad */
1265         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1266         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1267
1268         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1269         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1270         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1271         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1272
1273         /* This time with the texture */
1274         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1275         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1276
1277         IDirect3DDevice9_EndScene(device);
1278     }
1279
1280     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1281
1282     /* Center quad - should be white */
1283     color = getPixelColor(device, 320, 240);
1284     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1285     /* Some quad in the cleared part of the texture */
1286     color = getPixelColor(device, 170, 240);
1287     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1288     /* Part of the originally cleared back buffer */
1289     color = getPixelColor(device, 10, 10);
1290     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1291     if(0) {
1292         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1293          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1294          * the offscreen rendering mode this test would succeed or fail
1295          */
1296         color = getPixelColor(device, 10, 470);
1297         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1298     }
1299
1300 out:
1301     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1302
1303     /* restore things */
1304     if(backbuffer) {
1305         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1306         IDirect3DSurface9_Release(backbuffer);
1307     }
1308     if(offscreenTexture) {
1309         IDirect3DTexture9_Release(offscreenTexture);
1310     }
1311     if(offscreen) {
1312         IDirect3DSurface9_Release(offscreen);
1313     }
1314 }
1315
1316 /* This test tests fog in combination with shaders.
1317  * What's tested: linear fog (vertex and table) with pixel shader
1318  *                linear table fog with non foggy vertex shader
1319  *                vertex fog with foggy vertex shader, non-linear
1320  *                fog with shader, non-linear fog with foggy shader,
1321  *                linear table fog with foggy shader
1322  */
1323 static void fog_with_shader_test(IDirect3DDevice9 *device)
1324 {
1325     HRESULT hr;
1326     DWORD color;
1327     union {
1328         float f;
1329         DWORD i;
1330     } start, end;
1331     unsigned int i, j;
1332
1333     /* basic vertex shader without fog computation ("non foggy") */
1334     static const DWORD vertex_shader_code1[] = {
1335         0xfffe0101,                                                             /* vs_1_1                       */
1336         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1337         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1338         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1339         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1340         0x0000ffff
1341     };
1342     /* basic vertex shader with reversed fog computation ("foggy") */
1343     static const DWORD vertex_shader_code2[] = {
1344         0xfffe0101,                                                             /* vs_1_1                        */
1345         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1346         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1347         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1348         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1349         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1350         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1351         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1352         0x0000ffff
1353     };
1354     /* basic pixel shader */
1355     static const DWORD pixel_shader_code[] = {
1356         0xffff0101,                                                             /* ps_1_1     */
1357         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1358         0x0000ffff
1359     };
1360
1361     static struct vertex quad[] = {
1362         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
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     };
1367
1368     static const D3DVERTEXELEMENT9 decl_elements[] = {
1369         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1370         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1371         D3DDECL_END()
1372     };
1373
1374     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1375     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1376     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1377
1378     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1379     static const struct test_data_t {
1380         int vshader;
1381         int pshader;
1382         D3DFOGMODE vfog;
1383         D3DFOGMODE tfog;
1384         unsigned int color[11];
1385     } test_data[] = {
1386         /* only pixel shader: */
1387         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1388         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1389         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1390         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1391         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1392         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1393         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1394         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1395         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1396         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1397         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1398         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1399         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1400         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1401         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1402
1403         /* vertex shader */
1404         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1405         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1406          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1407         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1408         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1411         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1413
1414         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1415         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1417         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1418         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1419         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1420
1421         /* vertex shader and pixel shader */
1422         /* The next 4 tests would read the fog coord output, but it isn't available.
1423          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1424          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1425          * These tests should be disabled if some other hardware behaves differently
1426          */
1427         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1428         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1429         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1430         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1431         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1432         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1433         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1434         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1435         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1436         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1437         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1438         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1439
1440         /* These use the Z coordinate with linear table fog */
1441         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1442         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1443         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1444         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1445         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1446         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1447         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1448         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1449         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1450         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1451         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1452         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1453
1454         /* Non-linear table fog without fog coord */
1455         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1456         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1457         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1458         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1459         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1460         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1461
1462 #if 0  /* FIXME: these fail on GeForce 8500 */
1463         /* foggy vertex shader */
1464         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1465         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1468         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1469          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1470         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1471         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1472          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1473         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1474         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1475          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1476 #endif
1477
1478         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1479          * all using the fixed fog-coord linear fog
1480          */
1481         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1482         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1483          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1484         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1485         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1488         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1491         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1493
1494         /* These use table fog. Here the shader-provided fog coordinate is
1495          * ignored and the z coordinate used instead
1496          */
1497         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1498         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1499         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1500         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1501         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1502         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1503         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506     };
1507
1508     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1509     start.f=0.1f;
1510     end.f=0.9f;
1511
1512     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1513     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1514     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1515     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1516     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1517     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1518     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1519     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1520
1521     /* Setup initial states: No lighting, fog on, fog color */
1522     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1523     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1524     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1525     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1527     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1528     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1529     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1530
1531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1532     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1533     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1534     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1535
1536     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1538     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1539     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1540     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1541
1542     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1543     {
1544         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1545         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1546         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1547         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1548         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1549         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1550         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1551         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1552
1553         for(j=0; j < 11; j++)
1554         {
1555             /* Don't use the whole zrange to prevent rounding errors */
1556             quad[0].z = 0.001f + (float)j / 10.02f;
1557             quad[1].z = 0.001f + (float)j / 10.02f;
1558             quad[2].z = 0.001f + (float)j / 10.02f;
1559             quad[3].z = 0.001f + (float)j / 10.02f;
1560
1561             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1562             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1563
1564             hr = IDirect3DDevice9_BeginScene(device);
1565             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1566
1567             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1568             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1569
1570             hr = IDirect3DDevice9_EndScene(device);
1571             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1572
1573             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1574
1575             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1576             color = getPixelColor(device, 128, 240);
1577             ok(color_match(color, test_data[i].color[j], 13),
1578                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1579                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1580         }
1581     }
1582
1583     /* reset states */
1584     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1585     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1586     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1587     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1588     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1589     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1590     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1591     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1592
1593     IDirect3DVertexShader9_Release(vertex_shader[1]);
1594     IDirect3DVertexShader9_Release(vertex_shader[2]);
1595     IDirect3DPixelShader9_Release(pixel_shader[1]);
1596     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1597 }
1598
1599 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1600     unsigned int i, x, y;
1601     HRESULT hr;
1602     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1603     D3DLOCKED_RECT locked_rect;
1604
1605     /* Generate the textures */
1606     for(i=0; i<2; i++)
1607     {
1608         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1609                                             D3DPOOL_MANAGED, &texture[i], NULL);
1610         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1611
1612         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1613         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1614         for (y = 0; y < 128; ++y)
1615         {
1616             if(i)
1617             { /* Set up black texture with 2x2 texel white spot in the middle */
1618                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1619                 for (x = 0; x < 128; ++x)
1620                 {
1621                     if(y>62 && y<66 && x>62 && x<66)
1622                         *ptr++ = 0xffffffff;
1623                     else
1624                         *ptr++ = 0xff000000;
1625                 }
1626             }
1627             else
1628             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1629                * (if multiplied with bumpenvmat)
1630               */
1631                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1632                 for (x = 0; x < 128; ++x)
1633                 {
1634                     if(abs(x-64)>abs(y-64))
1635                     {
1636                         if(x < 64)
1637                             *ptr++ = 0xc000;
1638                         else
1639                             *ptr++ = 0x4000;
1640                     }
1641                     else
1642                     {
1643                         if(y < 64)
1644                             *ptr++ = 0x0040;
1645                         else
1646                             *ptr++ = 0x00c0;
1647                     }
1648                 }
1649             }
1650         }
1651         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1652         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1653
1654         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1655         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1656
1657         /* Disable texture filtering */
1658         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1659         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1661         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1662
1663         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1664         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1665         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1666         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1667     }
1668 }
1669
1670 /* test the behavior of the texbem instruction
1671  * with normal 2D and projective 2D textures
1672  */
1673 static void texbem_test(IDirect3DDevice9 *device)
1674 {
1675     HRESULT hr;
1676     DWORD color;
1677     int i;
1678
1679     static const DWORD pixel_shader_code[] = {
1680         0xffff0101,                         /* ps_1_1*/
1681         0x00000042, 0xb00f0000,             /* tex t0*/
1682         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1683         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1684         0x0000ffff
1685     };
1686     static const DWORD double_texbem_code[] =  {
1687         0xffff0103,                                         /* ps_1_3           */
1688         0x00000042, 0xb00f0000,                             /* tex t0           */
1689         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1690         0x00000042, 0xb00f0002,                             /* tex t2           */
1691         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1692         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1693         0x0000ffff                                          /* end              */
1694     };
1695
1696
1697     static const float quad[][7] = {
1698         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1699         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1700         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1701         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1702     };
1703     static const float quad_proj[][9] = {
1704         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1705         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1706         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1707         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1708     };
1709
1710     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1711         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1712         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1713         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1714         D3DDECL_END()
1715     },{
1716         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1717         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1718         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1719         D3DDECL_END()
1720     } };
1721
1722     /* use asymmetric matrix to test loading */
1723     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1724
1725     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1726     IDirect3DPixelShader9       *pixel_shader       = NULL;
1727     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1728     D3DLOCKED_RECT locked_rect;
1729
1730     generate_bumpmap_textures(device);
1731
1732     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1733     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1734     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1735     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1736     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1737
1738     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1739     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1740
1741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1742     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1743
1744     for(i=0; i<2; i++)
1745     {
1746         if(i)
1747         {
1748             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1749             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1750         }
1751
1752         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1753         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1754         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1755         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1756
1757         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1758         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1759         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1760         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1761
1762         hr = IDirect3DDevice9_BeginScene(device);
1763         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1764
1765         if(!i)
1766             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1767         else
1768             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1769         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1770
1771         hr = IDirect3DDevice9_EndScene(device);
1772         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1773
1774         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1775         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1776
1777         color = getPixelColor(device, 320-32, 240);
1778         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1779         color = getPixelColor(device, 320+32, 240);
1780         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1781         color = getPixelColor(device, 320, 240-32);
1782         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1783         color = getPixelColor(device, 320, 240+32);
1784         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1785
1786         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1787         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1788         IDirect3DPixelShader9_Release(pixel_shader);
1789
1790         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1791         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1792         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1793     }
1794
1795     /* clean up */
1796     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1797     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1798
1799     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1800     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1801
1802     for(i=0; i<2; i++)
1803     {
1804         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1805         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1806         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1807         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1808         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1809         IDirect3DTexture9_Release(texture);
1810     }
1811
1812     /* Test double texbem */
1813     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1814     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1815     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1816     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1817     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1818     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1819     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1820     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1821
1822     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1823     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1824     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1825     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1826
1827     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1828     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1829
1830     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1831     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1832     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1833     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1834     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1835     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1836
1837     {
1838         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1839 #define tex  0x00ff0000
1840 #define tex1 0x0000ff00
1841 #define origin 0x000000ff
1842         static const DWORD pixel_data[] = {
1843             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1844             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1845             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1846             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1847             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1848             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1849             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1850             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1851         };
1852 #undef tex1
1853 #undef tex2
1854 #undef origin
1855
1856         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1857         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1858         for(i = 0; i < 8; i++) {
1859             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1860         }
1861         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1862         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1863     }
1864
1865     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1866     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1867     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1868     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1869     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1870     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1872     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1873     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1874     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1875     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1876     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1877
1878     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1879     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1880     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1881     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1882     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1883     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1884
1885     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1886     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1887     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1888     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1889     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1890     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1891
1892     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1893     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1894     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1895     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1896     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1897     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1898     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1899     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1900
1901     hr = IDirect3DDevice9_BeginScene(device);
1902     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1903     if(SUCCEEDED(hr)) {
1904         static const float double_quad[] = {
1905             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1906              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1907             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1908              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1909         };
1910
1911         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1912         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1913         hr = IDirect3DDevice9_EndScene(device);
1914         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1915     }
1916     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1917     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1918     color = getPixelColor(device, 320, 240);
1919     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1920
1921     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1922     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1923     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1930     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1931
1932     IDirect3DPixelShader9_Release(pixel_shader);
1933     IDirect3DTexture9_Release(texture);
1934     IDirect3DTexture9_Release(texture1);
1935     IDirect3DTexture9_Release(texture2);
1936 }
1937
1938 static void z_range_test(IDirect3DDevice9 *device)
1939 {
1940     const struct vertex quad[] =
1941     {
1942         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1943         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1944         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1945         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1946     };
1947     const struct vertex quad2[] =
1948     {
1949         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1950         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1951         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1952         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1953     };
1954
1955     const struct tvertex quad3[] =
1956     {
1957         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1958         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1959         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1960         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1961     };
1962     const struct tvertex quad4[] =
1963     {
1964         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1965         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1966         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1967         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1968     };
1969     HRESULT hr;
1970     DWORD color;
1971     IDirect3DVertexShader9 *shader;
1972     IDirect3DVertexDeclaration9 *decl;
1973     D3DCAPS9 caps;
1974     const DWORD shader_code[] = {
1975         0xfffe0101,                                     /* vs_1_1           */
1976         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1977         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1978         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1979         0x0000ffff                                      /* end              */
1980     };
1981     static const D3DVERTEXELEMENT9 decl_elements[] = {
1982         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1983         D3DDECL_END()
1984     };
1985     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1986      * then call Present. Then clear the color buffer to make sure it has some defined content
1987      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1988      * by the depth value.
1989      */
1990     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1991     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1992     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1993     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1994
1995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1996     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1998     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1999     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2000     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2002     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2003     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2004     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2005
2006     hr = IDirect3DDevice9_BeginScene(device);
2007     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2008     if(hr == D3D_OK)
2009     {
2010         /* Test the untransformed vertex path */
2011         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2012         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2013         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2014         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2015         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2016         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2017
2018         /* Test the transformed vertex path */
2019         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2020         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2021
2022         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2023         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2025         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2026         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2027         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2028
2029         hr = IDirect3DDevice9_EndScene(device);
2030         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2031     }
2032
2033     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2034     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2035
2036     /* Do not test the exact corner pixels, but go pretty close to them */
2037
2038     /* Clipped because z > 1.0 */
2039     color = getPixelColor(device, 28, 238);
2040     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2041     color = getPixelColor(device, 28, 241);
2042     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2043
2044     /* Not clipped, > z buffer clear value(0.75) */
2045     color = getPixelColor(device, 31, 238);
2046     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2047     color = getPixelColor(device, 31, 241);
2048     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2049     color = getPixelColor(device, 100, 238);
2050     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2051     color = getPixelColor(device, 100, 241);
2052     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2053
2054     /* Not clipped, < z buffer clear value */
2055     color = getPixelColor(device, 104, 238);
2056     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2057     color = getPixelColor(device, 104, 241);
2058     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2059     color = getPixelColor(device, 318, 238);
2060     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2061     color = getPixelColor(device, 318, 241);
2062     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2063
2064     /* Clipped because z < 0.0 */
2065     color = getPixelColor(device, 321, 238);
2066     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2067     color = getPixelColor(device, 321, 241);
2068     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2069
2070     /* Test the shader path */
2071     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2072     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2073         skip("Vertex shaders not supported\n");
2074         goto out;
2075     }
2076     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2077     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2078     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2079     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2080
2081     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2082
2083     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2084     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2085     IDirect3DDevice9_SetVertexShader(device, shader);
2086     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2087
2088     hr = IDirect3DDevice9_BeginScene(device);
2089     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2090     if(hr == D3D_OK)
2091     {
2092         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2093         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2094         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2096         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2097         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2098         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2099         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2101         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2102
2103         hr = IDirect3DDevice9_EndScene(device);
2104         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2105     }
2106
2107     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2108     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2109     IDirect3DDevice9_SetVertexShader(device, NULL);
2110     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2111
2112     IDirect3DVertexDeclaration9_Release(decl);
2113     IDirect3DVertexShader9_Release(shader);
2114
2115     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2116     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2117     /* Z < 1.0 */
2118     color = getPixelColor(device, 28, 238);
2119     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2120
2121     /* 1.0 < z < 0.75 */
2122     color = getPixelColor(device, 31, 238);
2123     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2124     color = getPixelColor(device, 100, 238);
2125     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2126
2127     /* 0.75 < z < 0.0 */
2128     color = getPixelColor(device, 104, 238);
2129     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2130     color = getPixelColor(device, 318, 238);
2131     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2132
2133     /* 0.0 < z */
2134     color = getPixelColor(device, 321, 238);
2135     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2136
2137     out:
2138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2141     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 }
2145
2146 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2147 {
2148     D3DSURFACE_DESC desc;
2149     D3DLOCKED_RECT l;
2150     HRESULT hr;
2151     unsigned int x, y;
2152     DWORD *mem;
2153
2154     memset(&desc, 0, sizeof(desc));
2155     memset(&l, 0, sizeof(l));
2156     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2157     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2158     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2159     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2160     if(FAILED(hr)) return;
2161
2162     for(y = 0; y < desc.Height; y++)
2163     {
2164         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2165         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2166         {
2167             mem[x] = color;
2168         }
2169     }
2170     hr = IDirect3DSurface9_UnlockRect(surface);
2171     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2172 }
2173
2174 /* This tests a variety of possible StretchRect() situations */
2175 static void stretchrect_test(IDirect3DDevice9 *device)
2176 {
2177     HRESULT hr;
2178     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2179     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2180     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2181     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2182     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2183     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2184     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2185     IDirect3DSurface9 *orig_rt = NULL;
2186     DWORD color;
2187
2188     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2189     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2190     if(!orig_rt) {
2191         goto out;
2192     }
2193
2194     /* Create our temporary surfaces in system memory */
2195     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2196     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2197     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2198     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2199
2200     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2201     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2202     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2203     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2205     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2207
2208     /* Create render target surfaces */
2209     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2210     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2211     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2212     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2213     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2214     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2215
2216     /* Create render target textures */
2217     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2218     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2219     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2220     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2221     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2222     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2223     if (tex_rt32) {
2224         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2225         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2226     }
2227     if (tex_rt64) {
2228         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2229         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2230     }
2231     if (tex_rt_dest64) {
2232         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2233         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2234     }
2235
2236     /* Create regular textures in D3DPOOL_DEFAULT */
2237     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2238     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2239     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2240     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2241     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2242     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2243     if (tex32) {
2244         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2245         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2246     }
2247     if (tex64) {
2248         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2249         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2250     }
2251     if (tex_dest64) {
2252         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2253         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2254     }
2255
2256     /*********************************************************************
2257      * Tests for when the source parameter is an offscreen plain surface *
2258      *********************************************************************/
2259
2260     /* Fill the offscreen 64x64 surface with green */
2261     if (surf_offscreen64)
2262         fill_surface(surf_offscreen64, 0xff00ff00);
2263
2264     /* offscreenplain ==> offscreenplain, same size */
2265     if(surf_offscreen64 && surf_offscreen_dest64) {
2266         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2267         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2268
2269         if (hr == D3D_OK) {
2270             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2271             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2272         }
2273     }
2274
2275     /* offscreenplain ==> rendertarget texture, same size */
2276     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2277         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2278         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2279
2280         /* We can't lock rendertarget textures, so copy to our temp surface first */
2281         if (hr == D3D_OK) {
2282             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2283             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2284         }
2285
2286         if (hr == D3D_OK) {
2287             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2288             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2289         }
2290     }
2291
2292     /* offscreenplain ==> rendertarget surface, same size */
2293     if(surf_offscreen64 && surf_rt_dest64) {
2294         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2295         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2296
2297         if (hr == D3D_OK) {
2298             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2299             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2300         }
2301     }
2302
2303     /* offscreenplain ==> texture, same size (should fail) */
2304     if(surf_offscreen64 && surf_tex_dest64) {
2305         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2306         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2307     }
2308
2309     /* Fill the smaller offscreen surface with red */
2310     fill_surface(surf_offscreen32, 0xffff0000);
2311
2312     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2313     if(surf_offscreen32 && surf_offscreen64) {
2314         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2315         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2316     }
2317
2318     /* offscreenplain ==> rendertarget texture, scaling */
2319     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2320         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2321         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2322
2323         /* We can't lock rendertarget textures, so copy to our temp surface first */
2324         if (hr == D3D_OK) {
2325             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2326             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2327         }
2328
2329         if (hr == D3D_OK) {
2330             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2331             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2332         }
2333     }
2334
2335     /* offscreenplain ==> rendertarget surface, scaling */
2336     if(surf_offscreen32 && surf_rt_dest64) {
2337         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2338         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2339
2340         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2341         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2342     }
2343
2344     /* offscreenplain ==> texture, scaling (should fail) */
2345     if(surf_offscreen32 && surf_tex_dest64) {
2346         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2347         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2348     }
2349
2350     /************************************************************
2351      * Tests for when the source parameter is a regular texture *
2352      ************************************************************/
2353
2354     /* Fill the surface of the regular texture with blue */
2355     if (surf_tex64 && surf_temp64) {
2356         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2357         fill_surface(surf_temp64, 0xff0000ff);
2358         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2359         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2360     }
2361
2362     /* texture ==> offscreenplain, same size */
2363     if(surf_tex64 && surf_offscreen64) {
2364         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2365         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2366     }
2367
2368     /* texture ==> rendertarget texture, same size */
2369     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2370         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2371         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2372
2373         /* We can't lock rendertarget textures, so copy to our temp surface first */
2374         if (hr == D3D_OK) {
2375             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2376             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2377         }
2378
2379         if (hr == D3D_OK) {
2380             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2381             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2382         }
2383     }
2384
2385     /* texture ==> rendertarget surface, same size */
2386     if(surf_tex64 && surf_rt_dest64) {
2387         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2388         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2389
2390         if (hr == D3D_OK) {
2391             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2392             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2393         }
2394     }
2395
2396     /* texture ==> texture, same size (should fail) */
2397     if(surf_tex64 && surf_tex_dest64) {
2398         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2399         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2400     }
2401
2402     /* Fill the surface of the smaller regular texture with red */
2403     if (surf_tex32 && surf_temp32) {
2404         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2405         fill_surface(surf_temp32, 0xffff0000);
2406         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2407         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2408     }
2409
2410     /* texture ==> offscreenplain, scaling (should fail) */
2411     if(surf_tex32 && surf_offscreen64) {
2412         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2413         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2414     }
2415
2416     /* texture ==> rendertarget texture, scaling */
2417     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2418         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2419         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2420
2421         /* We can't lock rendertarget textures, so copy to our temp surface first */
2422         if (hr == D3D_OK) {
2423             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2424             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2425         }
2426
2427         if (hr == D3D_OK) {
2428             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2429             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2430         }
2431     }
2432
2433     /* texture ==> rendertarget surface, scaling */
2434     if(surf_tex32 && surf_rt_dest64) {
2435         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2436         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2437
2438         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2439         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2440     }
2441
2442     /* texture ==> texture, scaling (should fail) */
2443     if(surf_tex32 && surf_tex_dest64) {
2444         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2445         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2446     }
2447
2448     /*****************************************************************
2449      * Tests for when the source parameter is a rendertarget texture *
2450      *****************************************************************/
2451
2452     /* Fill the surface of the rendertarget texture with white */
2453     if (surf_tex_rt64 && surf_temp64) {
2454         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2455         fill_surface(surf_temp64, 0xffffffff);
2456         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2457         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2458     }
2459
2460     /* rendertarget texture ==> offscreenplain, same size */
2461     if(surf_tex_rt64 && surf_offscreen64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2463         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2464     }
2465
2466     /* rendertarget texture ==> rendertarget texture, same size */
2467     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2468         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2469         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2470
2471         /* We can't lock rendertarget textures, so copy to our temp surface first */
2472         if (hr == D3D_OK) {
2473             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2474             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2475         }
2476
2477         if (hr == D3D_OK) {
2478             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2479             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2480         }
2481     }
2482
2483     /* rendertarget texture ==> rendertarget surface, same size */
2484     if(surf_tex_rt64 && surf_rt_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2486         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2487
2488         if (hr == D3D_OK) {
2489             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2490             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2491         }
2492     }
2493
2494     /* rendertarget texture ==> texture, same size (should fail) */
2495     if(surf_tex_rt64 && surf_tex_dest64) {
2496         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2497         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2498     }
2499
2500     /* Fill the surface of the smaller rendertarget texture with red */
2501     if (surf_tex_rt32 && surf_temp32) {
2502         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2503         fill_surface(surf_temp32, 0xffff0000);
2504         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2505         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2506     }
2507
2508     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2509     if(surf_tex_rt32 && surf_offscreen64) {
2510         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2511         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2512     }
2513
2514     /* rendertarget texture ==> rendertarget texture, scaling */
2515     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2516         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2517         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2518
2519         /* We can't lock rendertarget textures, so copy to our temp surface first */
2520         if (hr == D3D_OK) {
2521             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2522             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2523         }
2524
2525         if (hr == D3D_OK) {
2526             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2527             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2528         }
2529     }
2530
2531     /* rendertarget texture ==> rendertarget surface, scaling */
2532     if(surf_tex_rt32 && surf_rt_dest64) {
2533         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2534         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2535
2536         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2537         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2538     }
2539
2540     /* rendertarget texture ==> texture, scaling (should fail) */
2541     if(surf_tex_rt32 && surf_tex_dest64) {
2542         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2543         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2544     }
2545
2546     /*****************************************************************
2547      * Tests for when the source parameter is a rendertarget surface *
2548      *****************************************************************/
2549
2550     /* Fill the surface of the rendertarget surface with black */
2551     if (surf_rt64)
2552         fill_surface(surf_rt64, 0xff000000);
2553
2554     /* rendertarget texture ==> offscreenplain, same size */
2555     if(surf_rt64 && surf_offscreen64) {
2556         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2557         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2558     }
2559
2560     /* rendertarget surface ==> rendertarget texture, same size */
2561     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2562         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2563         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2564
2565         /* We can't lock rendertarget textures, so copy to our temp surface first */
2566         if (hr == D3D_OK) {
2567             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2568             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2569         }
2570
2571         if (hr == D3D_OK) {
2572             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2573             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2574         }
2575     }
2576
2577     /* rendertarget surface ==> rendertarget surface, same size */
2578     if(surf_rt64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         if (hr == D3D_OK) {
2583             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2585         }
2586     }
2587
2588     /* rendertarget surface ==> texture, same size (should fail) */
2589     if(surf_rt64 && surf_tex_dest64) {
2590         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2591         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2592     }
2593
2594     /* Fill the surface of the smaller rendertarget texture with red */
2595     if (surf_rt32)
2596         fill_surface(surf_rt32, 0xffff0000);
2597
2598     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2599     if(surf_rt32 && surf_offscreen64) {
2600         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2601         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2602     }
2603
2604     /* rendertarget surface ==> rendertarget texture, scaling */
2605     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2606         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2607         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2608
2609         /* We can't lock rendertarget textures, so copy to our temp surface first */
2610         if (hr == D3D_OK) {
2611             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2612             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2613         }
2614
2615         if (hr == D3D_OK) {
2616             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2617             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2618         }
2619     }
2620
2621     /* rendertarget surface ==> rendertarget surface, scaling */
2622     if(surf_rt32 && surf_rt_dest64) {
2623         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2624         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2625
2626         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2627         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2628     }
2629
2630     /* rendertarget surface ==> texture, scaling (should fail) */
2631     if(surf_rt32 && surf_tex_dest64) {
2632         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2633         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2634     }
2635
2636     /* TODO: Test when source and destination RECT parameters are given... */
2637     /* TODO: Test format conversions */
2638
2639
2640 out:
2641     /* Clean up */
2642     if (surf_rt32)
2643         IDirect3DSurface9_Release(surf_rt32);
2644     if (surf_rt64)
2645         IDirect3DSurface9_Release(surf_rt64);
2646     if (surf_rt_dest64)
2647         IDirect3DSurface9_Release(surf_rt_dest64);
2648     if (surf_temp32)
2649         IDirect3DSurface9_Release(surf_temp32);
2650     if (surf_temp64)
2651         IDirect3DSurface9_Release(surf_temp64);
2652     if (surf_offscreen32)
2653         IDirect3DSurface9_Release(surf_offscreen32);
2654     if (surf_offscreen64)
2655         IDirect3DSurface9_Release(surf_offscreen64);
2656     if (surf_offscreen_dest64)
2657         IDirect3DSurface9_Release(surf_offscreen_dest64);
2658
2659     if (tex_rt32) {
2660         if (surf_tex_rt32)
2661             IDirect3DSurface9_Release(surf_tex_rt32);
2662         IDirect3DTexture9_Release(tex_rt32);
2663     }
2664     if (tex_rt64) {
2665         if (surf_tex_rt64)
2666             IDirect3DSurface9_Release(surf_tex_rt64);
2667         IDirect3DTexture9_Release(tex_rt64);
2668     }
2669     if (tex_rt_dest64) {
2670         if (surf_tex_rt_dest64)
2671             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2672         IDirect3DTexture9_Release(tex_rt_dest64);
2673     }
2674     if (tex32) {
2675         if (surf_tex32)
2676             IDirect3DSurface9_Release(surf_tex32);
2677         IDirect3DTexture9_Release(tex32);
2678     }
2679     if (tex64) {
2680         if (surf_tex64)
2681             IDirect3DSurface9_Release(surf_tex64);
2682         IDirect3DTexture9_Release(tex64);
2683     }
2684     if (tex_dest64) {
2685         if (surf_tex_dest64)
2686             IDirect3DSurface9_Release(surf_tex_dest64);
2687         IDirect3DTexture9_Release(tex_dest64);
2688     }
2689
2690     if (orig_rt) {
2691         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2692         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2693         IDirect3DSurface9_Release(orig_rt);
2694     }
2695 }
2696
2697 static void maxmip_test(IDirect3DDevice9 *device)
2698 {
2699     IDirect3DTexture9 *texture = NULL;
2700     IDirect3DSurface9 *surface = NULL;
2701     HRESULT hr;
2702     DWORD color;
2703     const float quads[] = {
2704         -1.0,   -1.0,   0.0,    0.0,    0.0,
2705         -1.0,    0.0,   0.0,    0.0,    1.0,
2706          0.0,   -1.0,   0.0,    1.0,    0.0,
2707          0.0,    0.0,   0.0,    1.0,    1.0,
2708
2709          0.0,   -1.0,   0.0,    0.0,    0.0,
2710          0.0,    0.0,   0.0,    0.0,    1.0,
2711          1.0,   -1.0,   0.0,    1.0,    0.0,
2712          1.0,    0.0,   0.0,    1.0,    1.0,
2713
2714          0.0,    0.0,   0.0,    0.0,    0.0,
2715          0.0,    1.0,   0.0,    0.0,    1.0,
2716          1.0,    0.0,   0.0,    1.0,    0.0,
2717          1.0,    1.0,   0.0,    1.0,    1.0,
2718
2719         -1.0,    0.0,   0.0,    0.0,    0.0,
2720         -1.0,    1.0,   0.0,    0.0,    1.0,
2721          0.0,    0.0,   0.0,    1.0,    0.0,
2722          0.0,    1.0,   0.0,    1.0,    1.0,
2723     };
2724
2725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2726     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2727
2728     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2729                                         &texture, NULL);
2730     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2731     if(!texture)
2732     {
2733         skip("Failed to create test texture\n");
2734         return;
2735     }
2736
2737     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2738     fill_surface(surface, 0xffff0000);
2739     IDirect3DSurface9_Release(surface);
2740     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2741     fill_surface(surface, 0xff00ff00);
2742     IDirect3DSurface9_Release(surface);
2743     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2744     fill_surface(surface, 0xff0000ff);
2745     IDirect3DSurface9_Release(surface);
2746
2747     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2748     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2749     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2750     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2751
2752     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2753     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2754
2755     hr = IDirect3DDevice9_BeginScene(device);
2756     if(SUCCEEDED(hr))
2757     {
2758         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2759         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2760         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2761         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2762
2763         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2764         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2766         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2767
2768         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2769         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2771         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2772
2773         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2774         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2776         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2777         hr = IDirect3DDevice9_EndScene(device);
2778     }
2779
2780     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2781     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2782     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2783     color = getPixelColor(device, 160, 360);
2784     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2785     color = getPixelColor(device, 160, 120);
2786     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2787     color = getPixelColor(device, 480, 120);
2788     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2789     color = getPixelColor(device, 480, 360);
2790     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2791
2792     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2793     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2794
2795     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2796     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2797
2798     hr = IDirect3DDevice9_BeginScene(device);
2799     if(SUCCEEDED(hr))
2800     {
2801         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2802         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2803         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2804         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2805
2806         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2807         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2809         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2810
2811         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2812         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2813         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2814         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2815
2816         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2817         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2818         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2819         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2820         hr = IDirect3DDevice9_EndScene(device);
2821     }
2822
2823     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2824     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2825     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2826      * samples from the highest level in the texture(level 2)
2827      */
2828     color = getPixelColor(device, 160, 360);
2829     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2830     color = getPixelColor(device, 160, 120);
2831     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2832     color = getPixelColor(device, 480, 120);
2833     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2834     color = getPixelColor(device, 480, 360);
2835     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2836
2837     hr = IDirect3DDevice9_BeginScene(device);
2838     if(SUCCEEDED(hr))
2839     {
2840         DWORD ret;
2841
2842         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2843         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2844         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2845         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2846         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2847         ret = IDirect3DTexture9_SetLOD(texture, 1);
2848         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2849         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2850         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2851
2852         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2853         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2854         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2855         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2856         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2857         ret = IDirect3DTexture9_SetLOD(texture, 2);
2858         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2859         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2860         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2861
2862         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2863         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2864         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2865         ret = IDirect3DTexture9_SetLOD(texture, 1);
2866         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2868         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2869
2870         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2871         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2872         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2873         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2874         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2875         ret = IDirect3DTexture9_SetLOD(texture, 1);
2876         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2877         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2878         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2879         hr = IDirect3DDevice9_EndScene(device);
2880     }
2881
2882     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2883     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2884     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2885      * samples from the highest level in the texture(level 2)
2886      */
2887     color = getPixelColor(device, 160, 360);
2888     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2889     color = getPixelColor(device, 160, 120);
2890     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2891     color = getPixelColor(device, 480, 120);
2892     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2893     color = getPixelColor(device, 480, 360);
2894     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2895
2896     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2897     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2898     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2899     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2900     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2901     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2902     IDirect3DTexture9_Release(texture);
2903 }
2904
2905 static void release_buffer_test(IDirect3DDevice9 *device)
2906 {
2907     IDirect3DVertexBuffer9 *vb = NULL;
2908     IDirect3DIndexBuffer9 *ib = NULL;
2909     HRESULT hr;
2910     BYTE *data;
2911     LONG ref;
2912
2913     static const struct vertex quad[] = {
2914         {-1.0,      -1.0,       0.1,        0xffff0000},
2915         {-1.0,       1.0,       0.1,        0xffff0000},
2916         { 1.0,       1.0,       0.1,        0xffff0000},
2917
2918         {-1.0,      -1.0,       0.1,        0xff00ff00},
2919         {-1.0,       1.0,       0.1,        0xff00ff00},
2920         { 1.0,       1.0,       0.1,        0xff00ff00}
2921     };
2922     short indices[] = {3, 4, 5};
2923
2924     /* Index and vertex buffers should always be creatable */
2925     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2926                                               D3DPOOL_MANAGED, &vb, NULL);
2927     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2928     if(!vb) {
2929         skip("Failed to create a vertex buffer\n");
2930         return;
2931     }
2932     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2933     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2934     if(!ib) {
2935         skip("Failed to create an index buffer\n");
2936         return;
2937     }
2938
2939     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2940     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2941     memcpy(data, quad, sizeof(quad));
2942     hr = IDirect3DVertexBuffer9_Unlock(vb);
2943     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2944
2945     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2946     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2947     memcpy(data, indices, sizeof(indices));
2948     hr = IDirect3DIndexBuffer9_Unlock(ib);
2949     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2950
2951     hr = IDirect3DDevice9_SetIndices(device, ib);
2952     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2953     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2954     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2955     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2956     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2957
2958     /* Now destroy the bound index buffer and draw again */
2959     ref = IDirect3DIndexBuffer9_Release(ib);
2960     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2961
2962     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2963     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2964
2965     hr = IDirect3DDevice9_BeginScene(device);
2966     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2967     if(SUCCEEDED(hr))
2968     {
2969         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2970          * making assumptions about the indices or vertices
2971          */
2972         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2973         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2974         hr = IDirect3DDevice9_EndScene(device);
2975         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2976     }
2977
2978     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2979     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2980
2981     hr = IDirect3DDevice9_SetIndices(device, NULL);
2982     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2983     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2984     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2985
2986     /* Index buffer was already destroyed as part of the test */
2987     IDirect3DVertexBuffer9_Release(vb);
2988 }
2989
2990 static void float_texture_test(IDirect3DDevice9 *device)
2991 {
2992     IDirect3D9 *d3d = NULL;
2993     HRESULT hr;
2994     IDirect3DTexture9 *texture = NULL;
2995     D3DLOCKED_RECT lr;
2996     float *data;
2997     DWORD color;
2998     float quad[] = {
2999         -1.0,      -1.0,       0.1,     0.0,    0.0,
3000         -1.0,       1.0,       0.1,     0.0,    1.0,
3001          1.0,      -1.0,       0.1,     1.0,    0.0,
3002          1.0,       1.0,       0.1,     1.0,    1.0,
3003     };
3004
3005     memset(&lr, 0, sizeof(lr));
3006     IDirect3DDevice9_GetDirect3D(device, &d3d);
3007     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3008                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3009         skip("D3DFMT_R32F textures not supported\n");
3010         goto out;
3011     }
3012
3013     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3014                                         D3DPOOL_MANAGED, &texture, NULL);
3015     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3016     if(!texture) {
3017         skip("Failed to create R32F texture\n");
3018         goto out;
3019     }
3020
3021     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3022     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3023     data = lr.pBits;
3024     *data = 0.0;
3025     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3026     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3027
3028     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3029     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3030
3031     hr = IDirect3DDevice9_BeginScene(device);
3032     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3033     if(SUCCEEDED(hr))
3034     {
3035         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3037
3038         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3039         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3040
3041         hr = IDirect3DDevice9_EndScene(device);
3042         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3043     }
3044     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3045     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3046
3047     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3048     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3049
3050     color = getPixelColor(device, 240, 320);
3051     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3052
3053 out:
3054     if(texture) IDirect3DTexture9_Release(texture);
3055     IDirect3D9_Release(d3d);
3056 }
3057
3058 static void g16r16_texture_test(IDirect3DDevice9 *device)
3059 {
3060     IDirect3D9 *d3d = NULL;
3061     HRESULT hr;
3062     IDirect3DTexture9 *texture = NULL;
3063     D3DLOCKED_RECT lr;
3064     DWORD *data;
3065     DWORD color;
3066     float quad[] = {
3067        -1.0,      -1.0,       0.1,     0.0,    0.0,
3068        -1.0,       1.0,       0.1,     0.0,    1.0,
3069         1.0,      -1.0,       0.1,     1.0,    0.0,
3070         1.0,       1.0,       0.1,     1.0,    1.0,
3071     };
3072
3073     memset(&lr, 0, sizeof(lr));
3074     IDirect3DDevice9_GetDirect3D(device, &d3d);
3075     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3076        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3077            skip("D3DFMT_G16R16 textures not supported\n");
3078            goto out;
3079     }
3080
3081     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3082                                         D3DPOOL_MANAGED, &texture, NULL);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3084     if(!texture) {
3085         skip("Failed to create D3DFMT_G16R16 texture\n");
3086         goto out;
3087     }
3088
3089     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3090     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3091     data = lr.pBits;
3092     *data = 0x0f00f000;
3093     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3094     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3095
3096     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3097     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3098
3099     hr = IDirect3DDevice9_BeginScene(device);
3100     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3101     if(SUCCEEDED(hr))
3102     {
3103         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3105
3106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3107         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3108
3109         hr = IDirect3DDevice9_EndScene(device);
3110         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3111     }
3112     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3113     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3114
3115     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3116     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3117
3118     color = getPixelColor(device, 240, 320);
3119     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3120        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3121
3122 out:
3123     if(texture) IDirect3DTexture9_Release(texture);
3124     IDirect3D9_Release(d3d);
3125 }
3126
3127 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3128 {
3129     HRESULT hr;
3130     IDirect3D9 *d3d;
3131     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3132     D3DCAPS9 caps;
3133     IDirect3DTexture9 *texture = NULL;
3134     IDirect3DVolumeTexture9 *volume = NULL;
3135     unsigned int x, y, z;
3136     D3DLOCKED_RECT lr;
3137     D3DLOCKED_BOX lb;
3138     DWORD color;
3139     UINT w, h;
3140     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3141     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3142                            0.0, 1.0, 0.0, 0.0,
3143                            0.0, 0.0, 1.0, 0.0,
3144                            0.0, 0.0, 0.0, 1.0};
3145     static const D3DVERTEXELEMENT9 decl_elements[] = {
3146         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3147         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3148         D3DDECL_END()
3149     };
3150     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3151         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3152         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3153         D3DDECL_END()
3154     };
3155     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3156         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3157         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3158         D3DDECL_END()
3159     };
3160     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3161                                                  0x00, 0xff, 0x00, 0x00,
3162                                                  0x00, 0x00, 0x00, 0x00,
3163                                                  0x00, 0x00, 0x00, 0x00};
3164
3165     memset(&lr, 0, sizeof(lr));
3166     memset(&lb, 0, sizeof(lb));
3167     IDirect3DDevice9_GetDirect3D(device, &d3d);
3168     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3169                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3170         fmt = D3DFMT_A16B16G16R16;
3171     }
3172     IDirect3D9_Release(d3d);
3173
3174     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3175     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3176     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3177     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3178     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3179     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3180     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3181     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3182     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3183     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3184     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3185     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3186     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3188     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3190     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3191     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3192     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3193     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3194     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3195     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3196     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3197     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3198
3199     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3200     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3201     w = min(1024, caps.MaxTextureWidth);
3202     h = min(1024, caps.MaxTextureHeight);
3203     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3204                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3205     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3206     if(!texture) {
3207         skip("Failed to create the test texture\n");
3208         return;
3209     }
3210
3211     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3212      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3213      * 1.0 in red and green for the x and y coords
3214      */
3215     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3216     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3217     for(y = 0; y < h; y++) {
3218         for(x = 0; x < w; x++) {
3219             double r_f = (double) y / (double) h;
3220             double g_f = (double) x / (double) w;
3221             if(fmt == D3DFMT_A16B16G16R16) {
3222                 unsigned short r, g;
3223                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3224                 r = (unsigned short) (r_f * 65536.0);
3225                 g = (unsigned short) (g_f * 65536.0);
3226                 dst[0] = r;
3227                 dst[1] = g;
3228                 dst[2] = 0;
3229                 dst[3] = 65535;
3230             } else {
3231                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3232                 unsigned char r = (unsigned char) (r_f * 255.0);
3233                 unsigned char g = (unsigned char) (g_f * 255.0);
3234                 dst[0] = 0;
3235                 dst[1] = g;
3236                 dst[2] = r;
3237                 dst[3] = 255;
3238             }
3239         }
3240     }
3241     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3242     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3243     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3244     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3245
3246     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3247     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3248     hr = IDirect3DDevice9_BeginScene(device);
3249     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3250     if(SUCCEEDED(hr))
3251     {
3252         float quad1[] = {
3253             -1.0,      -1.0,       0.1,     1.0,    1.0,
3254             -1.0,       0.0,       0.1,     1.0,    1.0,
3255              0.0,      -1.0,       0.1,     1.0,    1.0,
3256              0.0,       0.0,       0.1,     1.0,    1.0,
3257         };
3258         float quad2[] = {
3259             -1.0,       0.0,       0.1,     1.0,    1.0,
3260             -1.0,       1.0,       0.1,     1.0,    1.0,
3261              0.0,       0.0,       0.1,     1.0,    1.0,
3262              0.0,       1.0,       0.1,     1.0,    1.0,
3263         };
3264         float quad3[] = {
3265              0.0,       0.0,       0.1,     0.5,    0.5,
3266              0.0,       1.0,       0.1,     0.5,    0.5,
3267              1.0,       0.0,       0.1,     0.5,    0.5,
3268              1.0,       1.0,       0.1,     0.5,    0.5,
3269         };
3270         float quad4[] = {
3271              320,       480,       0.1,     1.0,    0.0,    1.0,
3272              320,       240,       0.1,     1.0,    0.0,    1.0,
3273              640,       480,       0.1,     1.0,    0.0,    1.0,
3274              640,       240,       0.1,     1.0,    0.0,    1.0,
3275         };
3276         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3277                           0.0, 0.0, 0.0, 0.0,
3278                           0.0, 0.0, 0.0, 0.0,
3279                           0.0, 0.0, 0.0, 0.0};
3280
3281         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3282         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3283         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3284         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3285         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3286
3287         /* What happens with transforms enabled? */
3288         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3289         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3290         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3291         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3292
3293         /* What happens if 4 coords are used, but only 2 given ?*/
3294         mat[8] = 1.0;
3295         mat[13] = 1.0;
3296         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3297         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3298         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3299         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3300         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3301         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3302
3303         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3304          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3305          * due to the coords in the vertices. (turns out red, indeed)
3306          */
3307         memset(mat, 0, sizeof(mat));
3308         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3309         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3310         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3311         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3312         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3313         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3314         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3315         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3316
3317         hr = IDirect3DDevice9_EndScene(device);
3318         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3319     }
3320     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3321     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3322     color = getPixelColor(device, 160, 360);
3323     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3324     color = getPixelColor(device, 160, 120);
3325     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3326     color = getPixelColor(device, 480, 120);
3327     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3328     color = getPixelColor(device, 480, 360);
3329     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3330
3331     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3332     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3333
3334     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3335     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3336     hr = IDirect3DDevice9_BeginScene(device);
3337     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3338     if(SUCCEEDED(hr))
3339     {
3340         float quad1[] = {
3341             -1.0,      -1.0,       0.1,     0.8,    0.2,
3342             -1.0,       0.0,       0.1,     0.8,    0.2,
3343              0.0,      -1.0,       0.1,     0.8,    0.2,
3344              0.0,       0.0,       0.1,     0.8,    0.2,
3345         };
3346         float quad2[] = {
3347             -1.0,       0.0,       0.1,     0.5,    1.0,
3348             -1.0,       1.0,       0.1,     0.5,    1.0,
3349              0.0,       0.0,       0.1,     0.5,    1.0,
3350              0.0,       1.0,       0.1,     0.5,    1.0,
3351         };
3352         float quad3[] = {
3353              0.0,       0.0,       0.1,     0.5,    1.0,
3354              0.0,       1.0,       0.1,     0.5,    1.0,
3355              1.0,       0.0,       0.1,     0.5,    1.0,
3356              1.0,       1.0,       0.1,     0.5,    1.0,
3357         };
3358         float quad4[] = {
3359              0.0,      -1.0,       0.1,     0.8,    0.2,
3360              0.0,       0.0,       0.1,     0.8,    0.2,
3361              1.0,      -1.0,       0.1,     0.8,    0.2,
3362              1.0,       0.0,       0.1,     0.8,    0.2,
3363         };
3364         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3365                           0.0, 0.0, 0.0, 0.0,
3366                           0.0, 1.0, 0.0, 0.0,
3367                           0.0, 0.0, 0.0, 0.0};
3368
3369         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3370          */
3371         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3372         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3373         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3374         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3375
3376         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3377         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3378
3379         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3380          * it behaves like COUNT2 because normal textures require 2 coords
3381          */
3382         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3383         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3384         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3385         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3386
3387         /* Just to be sure, the same as quad2 above */
3388         memset(mat, 0, sizeof(mat));
3389         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3390         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3391         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3392         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3393         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3394         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3395
3396         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3397          * used? And what happens to the first?
3398          */
3399         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3400         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3401         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3402         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3403
3404         hr = IDirect3DDevice9_EndScene(device);
3405         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3406     }
3407     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3409     color = getPixelColor(device, 160, 360);
3410     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3411     color = getPixelColor(device, 160, 120);
3412     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3413     color = getPixelColor(device, 480, 120);
3414     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3415        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3416     color = getPixelColor(device, 480, 360);
3417     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3418        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3419
3420     IDirect3DTexture9_Release(texture);
3421
3422     /* Test projected textures, without any fancy matrices */
3423     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3424     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3425     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3426     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3427     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3428     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3429     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3430     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3431
3432     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3433     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3434     for(x = 0; x < 4; x++) {
3435         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3436     }
3437     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3438     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3439     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3440     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3441
3442     hr = IDirect3DDevice9_BeginScene(device);
3443     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3444     if(SUCCEEDED(hr))
3445     {
3446         const float proj_quads[] = {
3447            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3448             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3449            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3450             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3451            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3452             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3453            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3454             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3455         };
3456
3457         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3458         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3459         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3460         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3461
3462         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3463         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3464         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3465         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3466
3467         hr = IDirect3DDevice9_EndScene(device);
3468         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3469     }
3470
3471     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3472     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3473     IDirect3DTexture9_Release(texture);
3474
3475     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3476     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3477     color = getPixelColor(device, 158, 118);
3478     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3479     color = getPixelColor(device, 162, 118);
3480     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3481     color = getPixelColor(device, 158, 122);
3482     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3483     color = getPixelColor(device, 162, 122);
3484     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3485
3486     color = getPixelColor(device, 158, 178);
3487     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3488     color = getPixelColor(device, 162, 178);
3489     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3490     color = getPixelColor(device, 158, 182);
3491     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3492     color = getPixelColor(device, 162, 182);
3493     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3494
3495     color = getPixelColor(device, 318, 118);
3496     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3497     color = getPixelColor(device, 322, 118);
3498     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3499     color = getPixelColor(device, 318, 122);
3500     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3501     color = getPixelColor(device, 322, 122);
3502     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3503
3504     color = getPixelColor(device, 318, 178);
3505     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3506     color = getPixelColor(device, 322, 178);
3507     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3508     color = getPixelColor(device, 318, 182);
3509     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3510     color = getPixelColor(device, 322, 182);
3511     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3512
3513     color = getPixelColor(device, 238, 298);
3514     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3515     color = getPixelColor(device, 242, 298);
3516     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3517     color = getPixelColor(device, 238, 302);
3518     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3519     color = getPixelColor(device, 242, 302);
3520     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3521
3522     color = getPixelColor(device, 238, 388);
3523     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3524     color = getPixelColor(device, 242, 388);
3525     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3526     color = getPixelColor(device, 238, 392);
3527     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3528     color = getPixelColor(device, 242, 392);
3529     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3530
3531     color = getPixelColor(device, 478, 298);
3532     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3533     color = getPixelColor(device, 482, 298);
3534     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3535     color = getPixelColor(device, 478, 302);
3536     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3537     color = getPixelColor(device, 482, 302);
3538     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3539
3540     color = getPixelColor(device, 478, 388);
3541     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3542     color = getPixelColor(device, 482, 388);
3543     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3544     color = getPixelColor(device, 478, 392);
3545     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3546     color = getPixelColor(device, 482, 392);
3547     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3548
3549     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3550     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3551     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3552      * Thus watch out if sampling from texels between 0 and 1.
3553      */
3554     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3555     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3556        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3557     if(!volume) {
3558         skip("Failed to create a volume texture\n");
3559         goto out;
3560     }
3561
3562     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3563     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3564     for(z = 0; z < 32; z++) {
3565         for(y = 0; y < 32; y++) {
3566             for(x = 0; x < 32; x++) {
3567                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3568                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3569                 float r_f = (float) x / 31.0;
3570                 float g_f = (float) y / 31.0;
3571                 float b_f = (float) z / 31.0;
3572
3573                 if(fmt == D3DFMT_A16B16G16R16) {
3574                     unsigned short *mem_s = mem;
3575                     mem_s[0]  = r_f * 65535.0;
3576                     mem_s[1]  = g_f * 65535.0;
3577                     mem_s[2]  = b_f * 65535.0;
3578                     mem_s[3]  = 65535;
3579                 } else {
3580                     unsigned char *mem_c = mem;
3581                     mem_c[0]  = b_f * 255.0;
3582                     mem_c[1]  = g_f * 255.0;
3583                     mem_c[2]  = r_f * 255.0;
3584                     mem_c[3]  = 255;
3585                 }
3586             }
3587         }
3588     }
3589     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3590     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3591
3592     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3593     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3594
3595     hr = IDirect3DDevice9_BeginScene(device);
3596     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3597     if(SUCCEEDED(hr))
3598     {
3599         float quad1[] = {
3600             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3601             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3602              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3603              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3604         };
3605         float quad2[] = {
3606             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3607             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3608              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3609              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3610         };
3611         float quad3[] = {
3612              0.0,       0.0,       0.1,     0.0,    0.0,
3613              0.0,       1.0,       0.1,     0.0,    0.0,
3614              1.0,       0.0,       0.1,     0.0,    0.0,
3615              1.0,       1.0,       0.1,     0.0,    0.0
3616         };
3617         float quad4[] = {
3618              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3619              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3620              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3621              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3622         };
3623         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3624                          0.0, 0.0, 1.0, 0.0,
3625                          0.0, 1.0, 0.0, 0.0,
3626                          0.0, 0.0, 0.0, 1.0};
3627         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3628         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3629
3630         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3631          * values
3632          */
3633         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3634         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3635         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3636         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3638         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3639
3640         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3641          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3642          * otherwise the w will be missing(blue).
3643          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3644          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3645          */
3646         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3647         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3648         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3649         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3650
3651         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3652         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3653         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3654         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3655         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3656         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3657         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3658         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3659         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3660
3661         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3662          * disable. ATI extends it up to the amount of values needed for the volume texture
3663          */
3664         memset(mat, 0, sizeof(mat));
3665         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3666         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3667         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3668         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3669         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3670         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3672         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3673
3674         hr = IDirect3DDevice9_EndScene(device);
3675         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3676     }
3677     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3678     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3679
3680     color = getPixelColor(device, 160, 360);
3681     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3682     color = getPixelColor(device, 160, 120);
3683     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3684        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3685     color = getPixelColor(device, 480, 120);
3686     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3687     color = getPixelColor(device, 480, 360);
3688     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3689
3690     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3691     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3692     hr = IDirect3DDevice9_BeginScene(device);
3693     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3694     if(SUCCEEDED(hr))
3695     {
3696         float quad1[] = {
3697             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3698             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3699              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3700              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3701         };
3702         float quad2[] = {
3703             -1.0,       0.0,       0.1,
3704             -1.0,       1.0,       0.1,
3705              0.0,       0.0,       0.1,
3706              0.0,       1.0,       0.1,
3707         };
3708         float quad3[] = {
3709              0.0,       0.0,       0.1,     1.0,
3710              0.0,       1.0,       0.1,     1.0,
3711              1.0,       0.0,       0.1,     1.0,
3712              1.0,       1.0,       0.1,     1.0
3713         };
3714         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3715                            0.0, 0.0, 0.0, 0.0,
3716                            0.0, 0.0, 0.0, 0.0,
3717                            0.0, 1.0, 0.0, 0.0};
3718         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3719                            1.0, 0.0, 0.0, 0.0,
3720                            0.0, 1.0, 0.0, 0.0,
3721                            0.0, 0.0, 1.0, 0.0};
3722         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3723         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3724
3725         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3726          */
3727         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3728         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3729         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3730         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3731         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3732         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3733
3734         /* None passed */
3735         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3736         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3737         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3738         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3739         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3740         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3741
3742         /* 4 used, 1 passed */
3743         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3744         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3745         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3746         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3748         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3749
3750         hr = IDirect3DDevice9_EndScene(device);
3751         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3752     }
3753     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3754     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3755     color = getPixelColor(device, 160, 360);
3756     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3757     color = getPixelColor(device, 160, 120);
3758     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3759     color = getPixelColor(device, 480, 120);
3760     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3761     /* Quad4: unused */
3762
3763     IDirect3DVolumeTexture9_Release(volume);
3764
3765     out:
3766     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3767     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3768     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3769     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3770     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3771     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3772     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3773     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3774     IDirect3DVertexDeclaration9_Release(decl);
3775     IDirect3DVertexDeclaration9_Release(decl2);
3776     IDirect3DVertexDeclaration9_Release(decl3);
3777 }
3778
3779 static void texdepth_test(IDirect3DDevice9 *device)
3780 {
3781     IDirect3DPixelShader9 *shader;
3782     HRESULT hr;
3783     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3784     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3785     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3786     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3787     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3788     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3789     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3790     DWORD shader_code[] = {
3791         0xffff0104,                                                                 /* ps_1_4               */
3792         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3793         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3794         0x0000fffd,                                                                 /* phase                */
3795         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3796         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3797         0x0000ffff                                                                  /* end                  */
3798     };
3799     DWORD color;
3800     float vertex[] = {
3801        -1.0,   -1.0,    0.0,
3802         1.0,   -1.0,    1.0,
3803        -1.0,    1.0,    0.0,
3804         1.0,    1.0,    1.0
3805     };
3806
3807     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3808     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3809
3810     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3811     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3812     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3813     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3814     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3815     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3816     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3817     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3818     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3819
3820     /* Fill the depth buffer with a gradient */
3821     hr = IDirect3DDevice9_BeginScene(device);
3822     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3823     if(SUCCEEDED(hr))
3824     {
3825         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3826         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3827         hr = IDirect3DDevice9_EndScene(device);
3828         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3829     }
3830
3831     /* Now perform the actual tests. Same geometry, but with the shader */
3832     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3833     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3834     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3835     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3836     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3837     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3838
3839     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 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
3852     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3853     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3854     color = getPixelColor(device, 158, 240);
3855     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3856     color = getPixelColor(device, 162, 240);
3857     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3858
3859     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3860
3861     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3862     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3863     hr = IDirect3DDevice9_BeginScene(device);
3864     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3865     if(SUCCEEDED(hr))
3866     {
3867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3868         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3869
3870         hr = IDirect3DDevice9_EndScene(device);
3871         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3872     }
3873
3874     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3875     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3876     color = getPixelColor(device, 318, 240);
3877     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3878     color = getPixelColor(device, 322, 240);
3879     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3880
3881     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3882
3883     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3884     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3885     hr = IDirect3DDevice9_BeginScene(device);
3886     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3887     if(SUCCEEDED(hr))
3888     {
3889         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3890         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3891
3892         hr = IDirect3DDevice9_EndScene(device);
3893         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3894     }
3895     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3896     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3897
3898     color = getPixelColor(device, 1, 240);
3899     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3900
3901     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3902
3903     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3904     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3905     hr = IDirect3DDevice9_BeginScene(device);
3906     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3907     if(SUCCEEDED(hr))
3908     {
3909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3910         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3911
3912         hr = IDirect3DDevice9_EndScene(device);
3913         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3914     }
3915     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3916     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3917     color = getPixelColor(device, 318, 240);
3918     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3919     color = getPixelColor(device, 322, 240);
3920     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3921
3922     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3923
3924     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3925     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3926     hr = IDirect3DDevice9_BeginScene(device);
3927     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3928     if(SUCCEEDED(hr))
3929     {
3930         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3931         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3932
3933         hr = IDirect3DDevice9_EndScene(device);
3934         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3935     }
3936     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3937     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3938
3939     color = getPixelColor(device, 1, 240);
3940     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3941
3942     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3943
3944     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3945     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3946     hr = IDirect3DDevice9_BeginScene(device);
3947     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3948     if(SUCCEEDED(hr))
3949     {
3950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3951         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3952
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
3959     color = getPixelColor(device, 638, 240);
3960     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3961
3962     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3963
3964     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3965     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3966     hr = IDirect3DDevice9_BeginScene(device);
3967     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3968     if(SUCCEEDED(hr))
3969     {
3970         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3971         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3972
3973         hr = IDirect3DDevice9_EndScene(device);
3974         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3975     }
3976     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3977     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3978
3979     color = getPixelColor(device, 638, 240);
3980     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3981
3982     /* Cleanup */
3983     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3984     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3985     IDirect3DPixelShader9_Release(shader);
3986
3987     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3988     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3989     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3990     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3991 }
3992
3993 static void texkill_test(IDirect3DDevice9 *device)
3994 {
3995     IDirect3DPixelShader9 *shader;
3996     HRESULT hr;
3997     DWORD color;
3998
3999     const float vertex[] = {
4000     /*                          bottom  top    right    left */
4001         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4002          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4003         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4004          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4005     };
4006
4007     DWORD shader_code_11[] = {
4008     0xffff0101,                                                             /* ps_1_1                     */
4009     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4010     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4011     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4012     0x0000ffff                                                              /* end                        */
4013     };
4014     DWORD shader_code_20[] = {
4015     0xffff0200,                                                             /* ps_2_0                     */
4016     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4017     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4018     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4019     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4020     0x0000ffff                                                              /* end                        */
4021     };
4022
4023     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4024     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4025     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4026     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4027
4028     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4030     hr = IDirect3DDevice9_BeginScene(device);
4031     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4032     if(SUCCEEDED(hr))
4033     {
4034         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4035         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4036         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4037         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4038         hr = IDirect3DDevice9_EndScene(device);
4039         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4040     }
4041     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4042     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4043     color = getPixelColor(device, 63, 46);
4044     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4045     color = getPixelColor(device, 66, 46);
4046     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4047     color = getPixelColor(device, 63, 49);
4048     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4049     color = getPixelColor(device, 66, 49);
4050     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4051
4052     color = getPixelColor(device, 578, 46);
4053     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4054     color = getPixelColor(device, 575, 46);
4055     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4056     color = getPixelColor(device, 578, 49);
4057     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4058     color = getPixelColor(device, 575, 49);
4059     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4060
4061     color = getPixelColor(device, 63, 430);
4062     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4063     color = getPixelColor(device, 63, 433);
4064     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4065     color = getPixelColor(device, 66, 433);
4066     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4067     color = getPixelColor(device, 66, 430);
4068     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4069
4070     color = getPixelColor(device, 578, 430);
4071     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4072     color = getPixelColor(device, 578, 433);
4073     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4074     color = getPixelColor(device, 575, 433);
4075     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4076     color = getPixelColor(device, 575, 430);
4077     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4078
4079     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4080     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4081     IDirect3DPixelShader9_Release(shader);
4082
4083     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4084     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4085     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4086     if(FAILED(hr)) {
4087         skip("Failed to create 2.0 test shader, most likely not supported\n");
4088         return;
4089     }
4090
4091     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4092     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4093     hr = IDirect3DDevice9_BeginScene(device);
4094     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4095     if(SUCCEEDED(hr))
4096     {
4097         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4098         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4099         hr = IDirect3DDevice9_EndScene(device);
4100         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4101     }
4102     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4103
4104     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4105     color = getPixelColor(device, 63, 46);
4106     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4107     color = getPixelColor(device, 66, 46);
4108     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4109     color = getPixelColor(device, 63, 49);
4110     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4111     color = getPixelColor(device, 66, 49);
4112     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4113
4114     color = getPixelColor(device, 578, 46);
4115     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4116     color = getPixelColor(device, 575, 46);
4117     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4118     color = getPixelColor(device, 578, 49);
4119     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4120     color = getPixelColor(device, 575, 49);
4121     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4122
4123     color = getPixelColor(device, 63, 430);
4124     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4125     color = getPixelColor(device, 63, 433);
4126     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4127     color = getPixelColor(device, 66, 433);
4128     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4129     color = getPixelColor(device, 66, 430);
4130     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4131
4132     color = getPixelColor(device, 578, 430);
4133     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4134     color = getPixelColor(device, 578, 433);
4135     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4136     color = getPixelColor(device, 575, 433);
4137     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4138     color = getPixelColor(device, 575, 430);
4139     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4140
4141     /* Cleanup */
4142     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4143     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4144     IDirect3DPixelShader9_Release(shader);
4145 }
4146
4147 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4148 {
4149     IDirect3D9 *d3d9;
4150     HRESULT hr;
4151     IDirect3DTexture9 *texture;
4152     IDirect3DPixelShader9 *shader;
4153     IDirect3DPixelShader9 *shader2;
4154     D3DLOCKED_RECT lr;
4155     DWORD color;
4156     DWORD shader_code[] = {
4157         0xffff0101,                             /* ps_1_1       */
4158         0x00000042, 0xb00f0000,                 /* tex t0       */
4159         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4160         0x0000ffff                              /* end          */
4161     };
4162     DWORD shader_code2[] = {
4163         0xffff0101,                             /* ps_1_1       */
4164         0x00000042, 0xb00f0000,                 /* tex t0       */
4165         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4166         0x0000ffff                              /* end          */
4167     };
4168
4169     float quad[] = {
4170        -1.0,   -1.0,   0.1,     0.5,    0.5,
4171         1.0,   -1.0,   0.1,     0.5,    0.5,
4172        -1.0,    1.0,   0.1,     0.5,    0.5,
4173         1.0,    1.0,   0.1,     0.5,    0.5,
4174     };
4175
4176     memset(&lr, 0, sizeof(lr));
4177     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4178     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4179                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4180     IDirect3D9_Release(d3d9);
4181     if(FAILED(hr)) {
4182         skip("No D3DFMT_X8L8V8U8 support\n");
4183     };
4184
4185     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4186     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4187
4188     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4189     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4190     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4191     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4192     *((DWORD *) lr.pBits) = 0x11ca3141;
4193     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4194     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4195
4196     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4197     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4198     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4199     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4200
4201     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4202     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4203     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4204     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4205     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4206     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4207
4208     hr = IDirect3DDevice9_BeginScene(device);
4209     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4210     if(SUCCEEDED(hr))
4211     {
4212         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4213         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4214
4215         hr = IDirect3DDevice9_EndScene(device);
4216         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4217     }
4218     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4219     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4220     color = getPixelColor(device, 578, 430);
4221     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4222        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4223
4224     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4225     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4226     hr = IDirect3DDevice9_BeginScene(device);
4227     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4228     if(SUCCEEDED(hr))
4229     {
4230         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4231         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4232
4233         hr = IDirect3DDevice9_EndScene(device);
4234         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4235     }
4236     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4237     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4238     color = getPixelColor(device, 578, 430);
4239     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4240
4241     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4242     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4243     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4244     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4245     IDirect3DPixelShader9_Release(shader);
4246     IDirect3DPixelShader9_Release(shader2);
4247     IDirect3DTexture9_Release(texture);
4248 }
4249
4250 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4251 {
4252     HRESULT hr;
4253     IDirect3D9 *d3d;
4254     IDirect3DTexture9 *texture = NULL;
4255     IDirect3DSurface9 *surface;
4256     DWORD color;
4257     const RECT r1 = {256, 256, 512, 512};
4258     const RECT r2 = {512, 256, 768, 512};
4259     const RECT r3 = {256, 512, 512, 768};
4260     const RECT r4 = {512, 512, 768, 768};
4261     unsigned int x, y;
4262     D3DLOCKED_RECT lr;
4263     memset(&lr, 0, sizeof(lr));
4264
4265     IDirect3DDevice9_GetDirect3D(device, &d3d);
4266     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4267        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4268         skip("No autogenmipmap support\n");
4269         IDirect3D9_Release(d3d);
4270         return;
4271     }
4272     IDirect3D9_Release(d3d);
4273
4274     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4275     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4276
4277     /* Make the mipmap big, so that a smaller mipmap is used
4278      */
4279     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4280                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4281     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4282
4283     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4284     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4285     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4286     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4287     for(y = 0; y < 1024; y++) {
4288         for(x = 0; x < 1024; x++) {
4289             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4290             POINT pt;
4291
4292             pt.x = x;
4293             pt.y = y;
4294             if(PtInRect(&r1, pt)) {
4295                 *dst = 0xffff0000;
4296             } else if(PtInRect(&r2, pt)) {
4297                 *dst = 0xff00ff00;
4298             } else if(PtInRect(&r3, pt)) {
4299                 *dst = 0xff0000ff;
4300             } else if(PtInRect(&r4, pt)) {
4301                 *dst = 0xff000000;
4302             } else {
4303                 *dst = 0xffffffff;
4304             }
4305         }
4306     }
4307     hr = IDirect3DSurface9_UnlockRect(surface);
4308     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4309     IDirect3DSurface9_Release(surface);
4310
4311     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4312     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4313     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4314     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4315
4316     hr = IDirect3DDevice9_BeginScene(device);
4317     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4318     if(SUCCEEDED(hr)) {
4319         const float quad[] =  {
4320            -0.5,   -0.5,    0.1,    0.0,    0.0,
4321            -0.5,    0.5,    0.1,    0.0,    1.0,
4322             0.5,   -0.5,    0.1,    1.0,    0.0,
4323             0.5,    0.5,    0.1,    1.0,    1.0
4324         };
4325
4326         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4327         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4328         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4329         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4330         hr = IDirect3DDevice9_EndScene(device);
4331         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4332     }
4333     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4334     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4335     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4336     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4337     IDirect3DTexture9_Release(texture);
4338
4339     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4340     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4341     color = getPixelColor(device, 200, 200);
4342     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4343     color = getPixelColor(device, 280, 200);
4344     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4345     color = getPixelColor(device, 360, 200);
4346     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4347     color = getPixelColor(device, 440, 200);
4348     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4349     color = getPixelColor(device, 200, 270);
4350     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4351     color = getPixelColor(device, 280, 270);
4352     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4353     color = getPixelColor(device, 360, 270);
4354     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4355     color = getPixelColor(device, 440, 270);
4356     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4357 }
4358
4359 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4360 {
4361     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4362     IDirect3DVertexDeclaration9 *decl;
4363     HRESULT hr;
4364     DWORD color;
4365     DWORD shader_code_11[] =  {
4366         0xfffe0101,                                         /* vs_1_1           */
4367         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4368         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4369         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4370         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4371         0x0000ffff                                          /* end              */
4372     };
4373     DWORD shader_code_11_2[] =  {
4374         0xfffe0101,                                         /* vs_1_1           */
4375         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4376         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4377         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4378         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4379         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4380         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4381         0x0000ffff                                          /* end              */
4382     };
4383     DWORD shader_code_20[] =  {
4384         0xfffe0200,                                         /* vs_2_0           */
4385         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4386         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4387         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4388         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4389         0x0000ffff                                          /* end              */
4390     };
4391     DWORD shader_code_20_2[] =  {
4392         0xfffe0200,                                         /* vs_2_0           */
4393         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4394         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4395         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4396         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4397         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4398         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4399         0x0000ffff                                          /* end              */
4400     };
4401     static const D3DVERTEXELEMENT9 decl_elements[] = {
4402         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4403         D3DDECL_END()
4404     };
4405     float quad1[] = {
4406         -1.0,   -1.0,   0.1,
4407          0.0,   -1.0,   0.1,
4408         -1.0,    0.0,   0.1,
4409          0.0,    0.0,   0.1
4410     };
4411     float quad2[] = {
4412          0.0,   -1.0,   0.1,
4413          1.0,   -1.0,   0.1,
4414          0.0,    0.0,   0.1,
4415          1.0,    0.0,   0.1
4416     };
4417     float quad3[] = {
4418          0.0,    0.0,   0.1,
4419          1.0,    0.0,   0.1,
4420          0.0,    1.0,   0.1,
4421          1.0,    1.0,   0.1
4422     };
4423     float quad4[] = {
4424         -1.0,    0.0,   0.1,
4425          0.0,    0.0,   0.1,
4426         -1.0,    1.0,   0.1,
4427          0.0,    1.0,   0.1
4428     };
4429     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4430     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4431
4432     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4434
4435     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4436     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4437     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4438     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4439     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4440     if(FAILED(hr)) shader_20 = NULL;
4441     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4442     if(FAILED(hr)) shader_20_2 = NULL;
4443     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4444     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4445
4446     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4447     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4448     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4449     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4450     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4451     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4452
4453     hr = IDirect3DDevice9_BeginScene(device);
4454     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4455     if(SUCCEEDED(hr))
4456     {
4457         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4458         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4459         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4460         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4461
4462         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4463         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4464         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4465         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4466
4467         if(shader_20) {
4468             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4469             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4470             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4471             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4472         }
4473
4474         if(shader_20_2) {
4475             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4476             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4477             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4478             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4479         }
4480
4481         hr = IDirect3DDevice9_EndScene(device);
4482         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4483     }
4484     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4485     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4486
4487     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4488     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4489     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4490     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4491
4492     color = getPixelColor(device, 160, 360);
4493     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4494        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4495     color = getPixelColor(device, 480, 360);
4496     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4497        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4498     if(shader_20) {
4499         color = getPixelColor(device, 160, 120);
4500         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4501            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4502     }
4503     if(shader_20_2) {
4504         color = getPixelColor(device, 480, 120);
4505         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4506            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4507     }
4508
4509     IDirect3DVertexDeclaration9_Release(decl);
4510     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4511     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4512     IDirect3DVertexShader9_Release(shader_11_2);
4513     IDirect3DVertexShader9_Release(shader_11);
4514 }
4515
4516 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4517 {
4518     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4519     HRESULT hr;
4520     DWORD color;
4521     DWORD shader_code_11[] =  {
4522         0xffff0101,                                         /* ps_1_1           */
4523         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4524         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4525         0x0000ffff                                          /* end              */
4526     };
4527     DWORD shader_code_12[] =  {
4528         0xffff0102,                                         /* ps_1_2           */
4529         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4530         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4531         0x0000ffff                                          /* end              */
4532     };
4533     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4534      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4535      * During development of this test, 1.3 shaders were verified too
4536      */
4537     DWORD shader_code_14[] =  {
4538         0xffff0104,                                         /* ps_1_4           */
4539         /* Try to make one constant local. It gets clamped too, although the binary contains
4540          * the bigger numbers
4541          */
4542         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4543         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4544         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4545         0x0000ffff                                          /* end              */
4546     };
4547     DWORD shader_code_20[] =  {
4548         0xffff0200,                                         /* ps_2_0           */
4549         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4550         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4551         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4552         0x0000ffff                                          /* end              */
4553     };
4554     float quad1[] = {
4555         -1.0,   -1.0,   0.1,
4556          0.0,   -1.0,   0.1,
4557         -1.0,    0.0,   0.1,
4558          0.0,    0.0,   0.1
4559     };
4560     float quad2[] = {
4561          0.0,   -1.0,   0.1,
4562          1.0,   -1.0,   0.1,
4563          0.0,    0.0,   0.1,
4564          1.0,    0.0,   0.1
4565     };
4566     float quad3[] = {
4567          0.0,    0.0,   0.1,
4568          1.0,    0.0,   0.1,
4569          0.0,    1.0,   0.1,
4570          1.0,    1.0,   0.1
4571     };
4572     float quad4[] = {
4573         -1.0,    0.0,   0.1,
4574          0.0,    0.0,   0.1,
4575         -1.0,    1.0,   0.1,
4576          0.0,    1.0,   0.1
4577     };
4578     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4579     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4580
4581     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4582     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4583
4584     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4585     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4586     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4587     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4588     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4589     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4590     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4591     if(FAILED(hr)) shader_20 = NULL;
4592
4593     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4594     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4595     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4596     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4597     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4598     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4599
4600     hr = IDirect3DDevice9_BeginScene(device);
4601     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4602     if(SUCCEEDED(hr))
4603     {
4604         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4605         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4606         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4607         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4608
4609         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4610         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4611         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4612         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4613
4614         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4615         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4616         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4617         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4618
4619         if(shader_20) {
4620             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4621             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4622             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4623             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4624         }
4625
4626         hr = IDirect3DDevice9_EndScene(device);
4627         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4628     }
4629     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4630     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4631
4632     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4633     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4634
4635     color = getPixelColor(device, 160, 360);
4636     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4637        "quad 1 has color %08x, expected 0x00808000\n", color);
4638     color = getPixelColor(device, 480, 360);
4639     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4640        "quad 2 has color %08x, expected 0x00808000\n", color);
4641     color = getPixelColor(device, 480, 120);
4642     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4643        "quad 3 has color %08x, expected 0x00808000\n", color);
4644     if(shader_20) {
4645         color = getPixelColor(device, 160, 120);
4646         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4647            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4648     }
4649
4650     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4651     IDirect3DPixelShader9_Release(shader_14);
4652     IDirect3DPixelShader9_Release(shader_12);
4653     IDirect3DPixelShader9_Release(shader_11);
4654 }
4655
4656 static void dp2add_ps_test(IDirect3DDevice9 *device)
4657 {
4658     IDirect3DPixelShader9 *shader_dp2add = NULL;
4659     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4660     HRESULT hr;
4661     DWORD color;
4662
4663     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4664      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4665      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4666      * r0 first.
4667      * The result here for the r,g,b components should be roughly 0.5:
4668      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4669     static const DWORD shader_code_dp2add[] =  {
4670         0xffff0200,                                                             /* ps_2_0                       */
4671         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4672
4673         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4674         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4675
4676         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4677         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4678         0x0000ffff                                                              /* end                          */
4679     };
4680
4681     /* Test the _sat modifier, too.  Result here should be:
4682      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4683      *      _SAT: ==> 1.0
4684      *   ADD: (1.0 + -0.5) = 0.5
4685      */
4686     static const DWORD shader_code_dp2add_sat[] =  {
4687         0xffff0200,                                                             /* ps_2_0                           */
4688         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4689
4690         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4691         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4692         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4693
4694         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4695         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4696         0x0000ffff                                                              /* end                              */
4697     };
4698
4699     const float quad[] = {
4700         -1.0,   -1.0,   0.1,
4701          1.0,   -1.0,   0.1,
4702         -1.0,    1.0,   0.1,
4703          1.0,    1.0,   0.1
4704     };
4705
4706
4707     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4708     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4709
4710     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4711     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4712
4713     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4714     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4715
4716     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4717     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4718
4719     if (shader_dp2add) {
4720
4721         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4722         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4723
4724         hr = IDirect3DDevice9_BeginScene(device);
4725         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4726         if(SUCCEEDED(hr))
4727         {
4728             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4729             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4730
4731             hr = IDirect3DDevice9_EndScene(device);
4732             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4733         }
4734         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4735         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4736
4737         color = getPixelColor(device, 360, 240);
4738         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4739                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4740
4741         IDirect3DPixelShader9_Release(shader_dp2add);
4742     } else {
4743         skip("dp2add shader creation failed\n");
4744     }
4745
4746     if (shader_dp2add_sat) {
4747
4748         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4749         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4750
4751         hr = IDirect3DDevice9_BeginScene(device);
4752         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4753         if(SUCCEEDED(hr))
4754         {
4755             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4756             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4757
4758             hr = IDirect3DDevice9_EndScene(device);
4759             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4760         }
4761         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4762         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4763
4764         color = getPixelColor(device, 360, 240);
4765         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4766                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4767
4768         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4769     } else {
4770         skip("dp2add shader creation failed\n");
4771     }
4772
4773     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4774     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4775 }
4776
4777 static void cnd_test(IDirect3DDevice9 *device)
4778 {
4779     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4780     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4781     HRESULT hr;
4782     DWORD color;
4783     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4784      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4785      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4786      */
4787     DWORD shader_code_11[] =  {
4788         0xffff0101,                                                                 /* ps_1_1               */
4789         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4790         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4791         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4792         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4793         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4794         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4795         0x0000ffff                                                                  /* end                  */
4796     };
4797     DWORD shader_code_12[] =  {
4798         0xffff0102,                                                                 /* ps_1_2               */
4799         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4800         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4801         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4802         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4803         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4804         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4805         0x0000ffff                                                                  /* end                  */
4806     };
4807     DWORD shader_code_13[] =  {
4808         0xffff0103,                                                                 /* ps_1_3               */
4809         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4810         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4811         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4812         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4813         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4814         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4815         0x0000ffff                                                                  /* end                  */
4816     };
4817     DWORD shader_code_14[] =  {
4818         0xffff0104,                                                                 /* ps_1_3               */
4819         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4820         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4821         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4822         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4823         0x0000ffff                                                                  /* end                  */
4824     };
4825
4826     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4827      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4828      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4829      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4830      * native CreatePixelShader returns an error.
4831      *
4832      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4833      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4834      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4835      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4836      */
4837     DWORD shader_code_11_coissue[] =  {
4838         0xffff0101,                                                             /* ps_1_1                   */
4839         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4840         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4841         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4842         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4843         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4844         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4845         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4846         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4847         /* 0x40000000 = D3DSI_COISSUE */
4848         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4849         0x0000ffff                                                              /* end                      */
4850     };
4851     DWORD shader_code_12_coissue[] =  {
4852         0xffff0102,                                                             /* ps_1_2                   */
4853         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4854         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4855         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4856         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4857         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4858         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4859         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4860         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4861         /* 0x40000000 = D3DSI_COISSUE */
4862         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4863         0x0000ffff                                                              /* end                      */
4864     };
4865     DWORD shader_code_13_coissue[] =  {
4866         0xffff0103,                                                             /* ps_1_3                   */
4867         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4868         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4869         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4870         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4871         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4872         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4873         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4874         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4875         /* 0x40000000 = D3DSI_COISSUE */
4876         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4877         0x0000ffff                                                              /* end                      */
4878     };
4879     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4880      * compare against 0.5
4881      */
4882     DWORD shader_code_14_coissue[] =  {
4883         0xffff0104,                                                             /* ps_1_4                   */
4884         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4885         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4886         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4887         /* 0x40000000 = D3DSI_COISSUE */
4888         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4889         0x0000ffff                                                              /* end                      */
4890     };
4891     float quad1[] = {
4892         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4893          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4894         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4895          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4896     };
4897     float quad2[] = {
4898          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4899          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4900          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4901          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4902     };
4903     float quad3[] = {
4904          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4905          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4906          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4907          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4908     };
4909     float quad4[] = {
4910         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4911          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4912         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4913          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4914     };
4915     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4916     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4917     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4918     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4919
4920     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4921     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4922
4923     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4924     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4925     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4926     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4927     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4928     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4929     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4930     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4931     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4932     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4933     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4934     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4935     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4936     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4937     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4938     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4939
4940     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4941     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4942     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4943     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4944     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4945     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4946
4947     hr = IDirect3DDevice9_BeginScene(device);
4948     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4949     if(SUCCEEDED(hr))
4950     {
4951         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4952         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4953         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4954         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4955
4956         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4957         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4958         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4959         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4960
4961         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4962         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4963         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4964         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4965
4966         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4967         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4969         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4970
4971         hr = IDirect3DDevice9_EndScene(device);
4972         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4973     }
4974     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4975     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4976
4977     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4978     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4979
4980     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4981     color = getPixelColor(device, 158, 118);
4982     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4983     color = getPixelColor(device, 162, 118);
4984     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4985     color = getPixelColor(device, 158, 122);
4986     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4987     color = getPixelColor(device, 162, 122);
4988     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4989
4990     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4991     color = getPixelColor(device, 158, 358);
4992     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4993     color = getPixelColor(device, 162, 358);
4994     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4995         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4996     color = getPixelColor(device, 158, 362);
4997     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4998     color = getPixelColor(device, 162, 362);
4999     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5000         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5001
5002     /* 1.2 shader */
5003     color = getPixelColor(device, 478, 358);
5004     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5005     color = getPixelColor(device, 482, 358);
5006     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5007         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5008     color = getPixelColor(device, 478, 362);
5009     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5010     color = getPixelColor(device, 482, 362);
5011     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5012         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5013
5014     /* 1.3 shader */
5015     color = getPixelColor(device, 478, 118);
5016     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5017     color = getPixelColor(device, 482, 118);
5018     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5019         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5020     color = getPixelColor(device, 478, 122);
5021     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5022     color = getPixelColor(device, 482, 122);
5023     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5024         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5025
5026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5027     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5028     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5029     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5030     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5031     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5032
5033     hr = IDirect3DDevice9_BeginScene(device);
5034     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5035     if(SUCCEEDED(hr))
5036     {
5037         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5038         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5039         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5040         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5041
5042         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5043         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5044         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5045         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5046
5047         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5048         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5049         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5050         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5051
5052         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5053         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5054         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5055         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5056
5057         hr = IDirect3DDevice9_EndScene(device);
5058         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5059     }
5060     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5061     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5062
5063     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5064     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5065
5066     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5067      * that we swapped the values in c1 and c2 to make the other tests return some color
5068      */
5069     color = getPixelColor(device, 158, 118);
5070     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5071     color = getPixelColor(device, 162, 118);
5072     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5073     color = getPixelColor(device, 158, 122);
5074     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5075     color = getPixelColor(device, 162, 122);
5076     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5077
5078     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5079     color = getPixelColor(device, 158, 358);
5080     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5081         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5082     color = getPixelColor(device, 162, 358);
5083     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5084         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5085     color = getPixelColor(device, 158, 362);
5086     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5087         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5088     color = getPixelColor(device, 162, 362);
5089     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5090         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5091
5092     /* 1.2 shader */
5093     color = getPixelColor(device, 478, 358);
5094     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5095         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5096     color = getPixelColor(device, 482, 358);
5097     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5098         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5099     color = getPixelColor(device, 478, 362);
5100     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5101         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5102     color = getPixelColor(device, 482, 362);
5103     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5104         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5105
5106     /* 1.3 shader */
5107     color = getPixelColor(device, 478, 118);
5108     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5109         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5110     color = getPixelColor(device, 482, 118);
5111     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5112         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5113     color = getPixelColor(device, 478, 122);
5114     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5115         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5116     color = getPixelColor(device, 482, 122);
5117     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5118         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5119
5120     IDirect3DPixelShader9_Release(shader_14_coissue);
5121     IDirect3DPixelShader9_Release(shader_13_coissue);
5122     IDirect3DPixelShader9_Release(shader_12_coissue);
5123     IDirect3DPixelShader9_Release(shader_11_coissue);
5124     IDirect3DPixelShader9_Release(shader_14);
5125     IDirect3DPixelShader9_Release(shader_13);
5126     IDirect3DPixelShader9_Release(shader_12);
5127     IDirect3DPixelShader9_Release(shader_11);
5128 }
5129
5130 static void nested_loop_test(IDirect3DDevice9 *device) {
5131     const DWORD shader_code[] = {
5132         0xffff0300,                                                             /* ps_3_0               */
5133         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5134         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5135         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5136         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5137         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5138         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5139         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5140         0x0000001d,                                                             /* endloop              */
5141         0x0000001d,                                                             /* endloop              */
5142         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5143         0x0000ffff                                                              /* end                  */
5144     };
5145     IDirect3DPixelShader9 *shader;
5146     HRESULT hr;
5147     DWORD color;
5148     const float quad[] = {
5149         -1.0,   -1.0,   0.1,
5150          1.0,   -1.0,   0.1,
5151         -1.0,    1.0,   0.1,
5152          1.0,    1.0,   0.1
5153     };
5154
5155     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5156     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5157     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5158     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5159     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5160     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5161     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5162     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5163
5164     hr = IDirect3DDevice9_BeginScene(device);
5165     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5166     if(SUCCEEDED(hr))
5167     {
5168         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5169         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5170         hr = IDirect3DDevice9_EndScene(device);
5171         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5172     }
5173     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5174     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5175
5176     color = getPixelColor(device, 360, 240);
5177     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5178        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5179
5180     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5181     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5182     IDirect3DPixelShader9_Release(shader);
5183 }
5184
5185 struct varying_test_struct
5186 {
5187     const DWORD             *shader_code;
5188     IDirect3DPixelShader9   *shader;
5189     DWORD                   color, color_rhw;
5190     const char              *name;
5191     BOOL                    todo, todo_rhw;
5192 };
5193
5194 struct hugeVertex
5195 {
5196     float pos_x,        pos_y,      pos_z,      rhw;
5197     float weight_1,     weight_2,   weight_3,   weight_4;
5198     float index_1,      index_2,    index_3,    index_4;
5199     float normal_1,     normal_2,   normal_3,   normal_4;
5200     float fog_1,        fog_2,      fog_3,      fog_4;
5201     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5202     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5203     float binormal_1,   binormal_2, binormal_3, binormal_4;
5204     float depth_1,      depth_2,    depth_3,    depth_4;
5205     DWORD diffuse, specular;
5206 };
5207
5208 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5209     /* dcl_position: fails to compile */
5210     const DWORD blendweight_code[] = {
5211         0xffff0300,                             /* ps_3_0                   */
5212         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5213         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5214         0x0000ffff                              /* end                      */
5215     };
5216     const DWORD blendindices_code[] = {
5217         0xffff0300,                             /* ps_3_0                   */
5218         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5219         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5220         0x0000ffff                              /* end                      */
5221     };
5222     const DWORD normal_code[] = {
5223         0xffff0300,                             /* ps_3_0                   */
5224         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5225         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5226         0x0000ffff                              /* end                      */
5227     };
5228     /* psize: fails? */
5229     const DWORD texcoord0_code[] = {
5230         0xffff0300,                             /* ps_3_0                   */
5231         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5232         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5233         0x0000ffff                              /* end                      */
5234     };
5235     const DWORD tangent_code[] = {
5236         0xffff0300,                             /* ps_3_0                   */
5237         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5238         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5239         0x0000ffff                              /* end                      */
5240     };
5241     const DWORD binormal_code[] = {
5242         0xffff0300,                             /* ps_3_0                   */
5243         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5244         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5245         0x0000ffff                              /* end                      */
5246     };
5247     /* tessfactor: fails */
5248     /* positiont: fails */
5249     const DWORD color_code[] = {
5250         0xffff0300,                             /* ps_3_0                   */
5251         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5252         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5253         0x0000ffff                              /* end                      */
5254     };
5255     const DWORD fog_code[] = {
5256         0xffff0300,                             /* ps_3_0                   */
5257         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5258         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5259         0x0000ffff                              /* end                      */
5260     };
5261     const DWORD depth_code[] = {
5262         0xffff0300,                             /* ps_3_0                   */
5263         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5264         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5265         0x0000ffff                              /* end                      */
5266     };
5267     const DWORD specular_code[] = {
5268         0xffff0300,                             /* ps_3_0                   */
5269         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5270         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5271         0x0000ffff                              /* end                      */
5272     };
5273     /* sample: fails */
5274
5275     struct varying_test_struct tests[] = {
5276        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5277        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5278        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5279        /* Why does dx not forward the texcoord? */
5280        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5281        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5282        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5283        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5284        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5285        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5286        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5287     };
5288     /* Declare a monster vertex type :-) */
5289     static const D3DVERTEXELEMENT9 decl_elements[] = {
5290         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5291         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5292         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5293         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5294         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5295         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5296         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5297         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5298         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5299         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5300         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5301         D3DDECL_END()
5302     };
5303     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5304         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5305         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5306         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5307         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5308         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5309         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5310         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5311         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5312         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5313         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5314         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5315         D3DDECL_END()
5316     };
5317     struct hugeVertex data[4] = {
5318         {
5319             -1.0,   -1.0,   0.1,    1.0,
5320              0.1,    0.1,   0.1,    0.1,
5321              0.2,    0.2,   0.2,    0.2,
5322              0.3,    0.3,   0.3,    0.3,
5323              0.4,    0.4,   0.4,    0.4,
5324              0.50,   0.55,  0.55,   0.55,
5325              0.6,    0.6,   0.6,    0.7,
5326              0.7,    0.7,   0.7,    0.6,
5327              0.8,    0.8,   0.8,    0.8,
5328              0xe6e6e6e6, /* 0.9 * 256 */
5329              0x224488ff  /* Nothing special */
5330         },
5331         {
5332              1.0,   -1.0,   0.1,    1.0,
5333              0.1,    0.1,   0.1,    0.1,
5334              0.2,    0.2,   0.2,    0.2,
5335              0.3,    0.3,   0.3,    0.3,
5336              0.4,    0.4,   0.4,    0.4,
5337              0.50,   0.55,  0.55,   0.55,
5338              0.6,    0.6,   0.6,    0.7,
5339              0.7,    0.7,   0.7,    0.6,
5340              0.8,    0.8,   0.8,    0.8,
5341              0xe6e6e6e6, /* 0.9 * 256 */
5342              0x224488ff /* Nothing special */
5343         },
5344         {
5345             -1.0,    1.0,   0.1,    1.0,
5346              0.1,    0.1,   0.1,    0.1,
5347              0.2,    0.2,   0.2,    0.2,
5348              0.3,    0.3,   0.3,    0.3,
5349              0.4,    0.4,   0.4,    0.4,
5350              0.50,   0.55,  0.55,   0.55,
5351              0.6,    0.6,   0.6,    0.7,
5352              0.7,    0.7,   0.7,    0.6,
5353              0.8,    0.8,   0.8,    0.8,
5354              0xe6e6e6e6, /* 0.9 * 256 */
5355              0x224488ff /* Nothing special */
5356         },
5357         {
5358              1.0,    1.0,   0.1,    1.0,
5359              0.1,    0.1,   0.1,    0.1,
5360              0.2,    0.2,   0.2,    0.2,
5361              0.3,    0.3,   0.3,    0.3,
5362              0.4,    0.4,   0.4,    0.4,
5363              0.50,   0.55,  0.55,   0.55,
5364              0.6,    0.6,   0.6,    0.7,
5365              0.7,    0.7,   0.7,    0.6,
5366              0.8,    0.8,   0.8,    0.8,
5367              0xe6e6e6e6, /* 0.9 * 256 */
5368              0x224488ff /* Nothing special */
5369         },
5370     };
5371     struct hugeVertex data2[4];
5372     IDirect3DVertexDeclaration9 *decl;
5373     IDirect3DVertexDeclaration9 *decl2;
5374     HRESULT hr;
5375     unsigned int i;
5376     DWORD color, r, g, b, r_e, g_e, b_e;
5377     BOOL drawok;
5378
5379     memcpy(data2, data, sizeof(data2));
5380     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5381     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5382     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5383     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5384
5385     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5386     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5387     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5388     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5389     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5390     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5391
5392     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5393     {
5394         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5395         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5396            tests[i].name, hr);
5397     }
5398
5399     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5400     {
5401         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5402         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5403
5404         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5405         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5406
5407         hr = IDirect3DDevice9_BeginScene(device);
5408         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5409         drawok = FALSE;
5410         if(SUCCEEDED(hr))
5411         {
5412             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5413             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5414             drawok = SUCCEEDED(hr);
5415             hr = IDirect3DDevice9_EndScene(device);
5416             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5417         }
5418         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5419         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5420
5421         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5422          * the failure and do not check the color if it failed
5423          */
5424         if(!drawok) {
5425             continue;
5426         }
5427
5428         color = getPixelColor(device, 360, 240);
5429         r = color & 0x00ff0000 >> 16;
5430         g = color & 0x0000ff00 >>  8;
5431         b = color & 0x000000ff;
5432         r_e = tests[i].color & 0x00ff0000 >> 16;
5433         g_e = tests[i].color & 0x0000ff00 >>  8;
5434         b_e = tests[i].color & 0x000000ff;
5435
5436         if(tests[i].todo) {
5437             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5438                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5439                          tests[i].name, color, tests[i].color);
5440         } else {
5441             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5442                "Test %s returned color 0x%08x, expected 0x%08x\n",
5443                tests[i].name, color, tests[i].color);
5444         }
5445     }
5446
5447     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5448     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5449     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5450     {
5451         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5452         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5453
5454         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5455         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5456
5457         hr = IDirect3DDevice9_BeginScene(device);
5458         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5459         if(SUCCEEDED(hr))
5460         {
5461             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5462             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5463             hr = IDirect3DDevice9_EndScene(device);
5464             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5465         }
5466         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5467         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5468
5469         color = getPixelColor(device, 360, 240);
5470         r = color & 0x00ff0000 >> 16;
5471         g = color & 0x0000ff00 >>  8;
5472         b = color & 0x000000ff;
5473         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5474         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5475         b_e = tests[i].color_rhw & 0x000000ff;
5476
5477         if(tests[i].todo_rhw) {
5478             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5479              * pipeline
5480              */
5481             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5482                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5483                          tests[i].name, color, tests[i].color_rhw);
5484         } else {
5485             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5486                "Test %s returned color 0x%08x, expected 0x%08x\n",
5487                tests[i].name, color, tests[i].color_rhw);
5488         }
5489     }
5490
5491     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5492     {
5493         IDirect3DPixelShader9_Release(tests[i].shader);
5494     }
5495
5496     IDirect3DVertexDeclaration9_Release(decl2);
5497     IDirect3DVertexDeclaration9_Release(decl);
5498 }
5499
5500 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5501     static const DWORD ps_code[] = {
5502     0xffff0300,                                                             /* ps_3_0                       */
5503     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5504     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5505     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5506     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5507     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5508     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5509     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5510     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5511     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5512
5513     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5514     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5515     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5516     0x0000001d,                                                             /* endloop                      */
5517     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5518     0x0000ffff                                                              /* end                          */
5519     };
5520     static const DWORD vs_1_code[] = {
5521     0xfffe0101,                                                             /* vs_1_1                       */
5522     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5523     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5524     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5525     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5526     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5527     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5528     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5529     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5530     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5531     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5532     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5533     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5534     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5535     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5536     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5537     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5538     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5539     0x0000ffff
5540     };
5541     DWORD vs_2_code[] = {
5542     0xfffe0200,                                                             /* vs_2_0                       */
5543     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5544     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5545     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5546     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5547     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5548     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5549     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5550     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5551     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5552     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5553     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5554     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5555     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5556     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5557     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5558     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5559     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5560     0x0000ffff                                                              /* end                          */
5561     };
5562     /* TODO: Define normal, tangent, blendweight and depth here */
5563     static const DWORD vs_3_code[] = {
5564     0xfffe0300,                                                             /* vs_3_0                       */
5565     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5566     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5567     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5568     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5569     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5570     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5571     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5572     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5573     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5574     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5575     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5576     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5577     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5578     0x0000ffff                                                              /* end                          */
5579     };
5580     float quad1[] =  {
5581         -1.0,   -1.0,   0.1,
5582          0.0,   -1.0,   0.1,
5583         -1.0,    0.0,   0.1,
5584          0.0,    0.0,   0.1
5585     };
5586     float quad2[] =  {
5587          0.0,   -1.0,   0.1,
5588          1.0,   -1.0,   0.1,
5589          0.0,    0.0,   0.1,
5590          1.0,    0.0,   0.1
5591     };
5592     float quad3[] =  {
5593         -1.0,    0.0,   0.1,
5594          0.0,    0.0,   0.1,
5595         -1.0,    1.0,   0.1,
5596          0.0,    1.0,   0.1
5597     };
5598
5599     HRESULT hr;
5600     DWORD color;
5601     IDirect3DPixelShader9 *pixelshader = NULL;
5602     IDirect3DVertexShader9 *vs_1_shader = NULL;
5603     IDirect3DVertexShader9 *vs_2_shader = NULL;
5604     IDirect3DVertexShader9 *vs_3_shader = NULL;
5605
5606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5607
5608     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5609     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5610     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5611     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5612     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5613     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5614     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5615     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5616     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5617     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5618     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5619
5620     hr = IDirect3DDevice9_BeginScene(device);
5621     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5622     if(SUCCEEDED(hr))
5623     {
5624         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5625         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5626         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5627         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5628
5629         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5630         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5631         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5632         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5633
5634         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5635         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5636         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5637         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5638
5639         hr = IDirect3DDevice9_EndScene(device);
5640         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5641     }
5642     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5643     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5644
5645     color = getPixelColor(device, 160, 120);
5646     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5647        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5648     /* Accept two ways of oFog handling:
5649      *
5650      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5651      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5652      *
5653      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5654      *    This happens with software vertex processing and on Intel cards
5655      *
5656      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5657      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5658      */
5659     color = getPixelColor(device, 160, 360);
5660     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5661        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5662        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5663     color = getPixelColor(device, 480, 360);
5664     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5665        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5666        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5667
5668     /* cleanup */
5669     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5670     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5671     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5672     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5673     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5674     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5675     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5676     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5677 }
5678
5679 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5680     static const DWORD vs_code[] = {
5681     0xfffe0300,                                                             /* vs_3_0                       */
5682     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5683     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5684     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5685     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5686     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5687     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5688     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5689     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5690     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5691     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5692     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5693     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5694     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5695
5696     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5697     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5698     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5699     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5700     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5701     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5702     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5703     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5704     0x0000ffff                                                              /* end                          */
5705     };
5706     static const DWORD ps_1_code[] = {
5707     0xffff0104,                                                             /* ps_1_4                       */
5708     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5709     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5710     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5711     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5712     0x0000ffff                                                              /* end                          */
5713     };
5714     static const DWORD ps_2_code[] = {
5715     0xffff0200,                                                             /* ps_2_0                       */
5716     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5717     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5718     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5719
5720     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5721     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5722     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5723     0x0000ffff                                                              /* end                          */
5724     };
5725     static const DWORD ps_3_code[] = {
5726     0xffff0300,                                                             /* ps_3_0                       */
5727     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5728     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5729     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5730
5731     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5732     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5733     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5734     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5735     0x0000ffff                                                              /* end                          */
5736     };
5737
5738     float quad1[] =  {
5739         -1.0,   -1.0,   0.1,
5740          0.0,   -1.0,   0.1,
5741         -1.0,    0.0,   0.1,
5742          0.0,    0.0,   0.1
5743     };
5744     float quad2[] =  {
5745          0.0,   -1.0,   0.1,
5746          1.0,   -1.0,   0.1,
5747          0.0,    0.0,   0.1,
5748          1.0,    0.0,   0.1
5749     };
5750     float quad3[] =  {
5751         -1.0,    0.0,   0.1,
5752          0.0,    0.0,   0.1,
5753         -1.0,    1.0,   0.1,
5754          0.0,    1.0,   0.1
5755     };
5756     float quad4[] =  {
5757          0.0,    0.0,   0.1,
5758          1.0,    0.0,   0.1,
5759          0.0,    1.0,   0.1,
5760          1.0,    1.0,   0.1
5761     };
5762
5763     HRESULT hr;
5764     DWORD color;
5765     IDirect3DVertexShader9 *vertexshader = NULL;
5766     IDirect3DPixelShader9 *ps_1_shader = NULL;
5767     IDirect3DPixelShader9 *ps_2_shader = NULL;
5768     IDirect3DPixelShader9 *ps_3_shader = NULL;
5769     IDirect3DTexture9 *texture = NULL;
5770     D3DLOCKED_RECT lr;
5771     unsigned int x, y;
5772
5773     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5774
5775     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5776     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5777     if(FAILED(hr)) {
5778         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5779         return;
5780     }
5781     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5782     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5783     for(y = 0; y < 512; y++) {
5784         for(x = 0; x < 512; x++) {
5785             double r_f = (double) x / (double) 512;
5786             double g_f = (double) y / (double) 512;
5787             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5788             unsigned short r = (unsigned short) (r_f * 65535.0);
5789             unsigned short g = (unsigned short) (g_f * 65535.0);
5790             dst[0] = r;
5791             dst[1] = g;
5792             dst[2] = 0;
5793             dst[3] = 65535;
5794         }
5795     }
5796     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5797     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5798
5799     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5800     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5801     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5802     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5803     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5804     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5805     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5806     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5807     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5808     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5809     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5810
5811     hr = IDirect3DDevice9_BeginScene(device);
5812     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5813     if(SUCCEEDED(hr))
5814     {
5815         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5816         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5818         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5819
5820         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5821         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5822         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5823         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5824
5825         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5826         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5827         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5828         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5829
5830         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5831         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5832         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5833         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5834         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5835         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5836         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5837         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5838         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5839         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5840
5841         hr = IDirect3DDevice9_EndScene(device);
5842         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5843     }
5844     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5845     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5846
5847     color = getPixelColor(device, 160, 120);
5848     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5849        (color & 0x0000ff00) == 0x0000ff00 &&
5850        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5851        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5852     color = getPixelColor(device, 160, 360);
5853     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5854        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5855        (color & 0x000000ff) == 0x00000000,
5856        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5857     color = getPixelColor(device, 480, 360);
5858     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5859        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5860        (color & 0x000000ff) == 0x00000000,
5861        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5862     color = getPixelColor(device, 480, 160);
5863     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5864        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5865        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5866        (color & 0x000000ff) == 0x00000000),
5867        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5868
5869     /* cleanup */
5870     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5871     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5872     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5873     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5874     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5875     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5876     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5877     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5878     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5879     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5880     if(texture) IDirect3DTexture9_Release(texture);
5881 }
5882
5883 static void test_compare_instructions(IDirect3DDevice9 *device)
5884 {
5885     DWORD shader_sge_vec_code[] = {
5886         0xfffe0101,                                         /* vs_1_1                   */
5887         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5888         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5889         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5890         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5891         0x0000ffff                                          /* end                      */
5892     };
5893     DWORD shader_slt_vec_code[] = {
5894         0xfffe0101,                                         /* vs_1_1                   */
5895         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5896         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5897         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5898         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5899         0x0000ffff                                          /* end                      */
5900     };
5901     DWORD shader_sge_scalar_code[] = {
5902         0xfffe0101,                                         /* vs_1_1                   */
5903         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5904         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5905         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5906         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5907         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5908         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5909         0x0000ffff                                          /* end                      */
5910     };
5911     DWORD shader_slt_scalar_code[] = {
5912         0xfffe0101,                                         /* vs_1_1                   */
5913         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5914         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5915         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5916         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5917         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5918         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5919         0x0000ffff                                          /* end                      */
5920     };
5921     IDirect3DVertexShader9 *shader_sge_vec;
5922     IDirect3DVertexShader9 *shader_slt_vec;
5923     IDirect3DVertexShader9 *shader_sge_scalar;
5924     IDirect3DVertexShader9 *shader_slt_scalar;
5925     HRESULT hr, color;
5926     float quad1[] =  {
5927         -1.0,   -1.0,   0.1,
5928          0.0,   -1.0,   0.1,
5929         -1.0,    0.0,   0.1,
5930          0.0,    0.0,   0.1
5931     };
5932     float quad2[] =  {
5933          0.0,   -1.0,   0.1,
5934          1.0,   -1.0,   0.1,
5935          0.0,    0.0,   0.1,
5936          1.0,    0.0,   0.1
5937     };
5938     float quad3[] =  {
5939         -1.0,    0.0,   0.1,
5940          0.0,    0.0,   0.1,
5941         -1.0,    1.0,   0.1,
5942          0.0,    1.0,   0.1
5943     };
5944     float quad4[] =  {
5945          0.0,    0.0,   0.1,
5946          1.0,    0.0,   0.1,
5947          0.0,    1.0,   0.1,
5948          1.0,    1.0,   0.1
5949     };
5950     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5951     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5952
5953     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5954
5955     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5956     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5957     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5958     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5959     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5960     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5961     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5962     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5963     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5964     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5965     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5966     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5967     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5968     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5969
5970     hr = IDirect3DDevice9_BeginScene(device);
5971     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5972     if(SUCCEEDED(hr))
5973     {
5974         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5975         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5976         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5977         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5978
5979         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5980         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5981         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5982         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5983
5984         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5985         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5988
5989         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5990         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5991
5992         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5993         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5994         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5995         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5996
5997         hr = IDirect3DDevice9_EndScene(device);
5998         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5999     }
6000
6001     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6002     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6003     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6004     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6005
6006     color = getPixelColor(device, 160, 360);
6007     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6008     color = getPixelColor(device, 480, 360);
6009     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6010     color = getPixelColor(device, 160, 120);
6011     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6012     color = getPixelColor(device, 480, 160);
6013     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6014
6015     IDirect3DVertexShader9_Release(shader_sge_vec);
6016     IDirect3DVertexShader9_Release(shader_slt_vec);
6017     IDirect3DVertexShader9_Release(shader_sge_scalar);
6018     IDirect3DVertexShader9_Release(shader_slt_scalar);
6019 }
6020
6021 static void test_vshader_input(IDirect3DDevice9 *device)
6022 {
6023     DWORD swapped_shader_code_3[] = {
6024         0xfffe0300,                                         /* vs_3_0               */
6025         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6026         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6027         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6028         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6029         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6030         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6031         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6032         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6033         0x0000ffff                                          /* end                  */
6034     };
6035     DWORD swapped_shader_code_1[] = {
6036         0xfffe0101,                                         /* vs_1_1               */
6037         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6038         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6039         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6040         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6041         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6042         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6043         0x0000ffff                                          /* end                  */
6044     };
6045     DWORD swapped_shader_code_2[] = {
6046         0xfffe0200,                                         /* vs_2_0               */
6047         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6048         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6049         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6050         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6051         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6052         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6053         0x0000ffff                                          /* end                  */
6054     };
6055     DWORD texcoord_color_shader_code_3[] = {
6056         0xfffe0300,                                         /* vs_3_0               */
6057         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6058         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6059         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6060         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6061         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6062         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6063         0x0000ffff                                          /* end                  */
6064     };
6065     DWORD texcoord_color_shader_code_2[] = {
6066         0xfffe0200,                                         /* vs_2_0               */
6067         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6068         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6069         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6070         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6071         0x0000ffff                                          /* end                  */
6072     };
6073     DWORD texcoord_color_shader_code_1[] = {
6074         0xfffe0101,                                         /* vs_1_1               */
6075         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6076         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6077         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6078         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6079         0x0000ffff                                          /* end                  */
6080     };
6081     DWORD color_color_shader_code_3[] = {
6082         0xfffe0300,                                         /* vs_3_0               */
6083         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6084         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6085         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6086         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6087         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6088         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6089         0x0000ffff                                          /* end                  */
6090     };
6091     DWORD color_color_shader_code_2[] = {
6092         0xfffe0200,                                         /* vs_2_0               */
6093         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6094         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6095         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6096         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6097         0x0000ffff                                          /* end                  */
6098     };
6099     DWORD color_color_shader_code_1[] = {
6100         0xfffe0101,                                         /* vs_1_1               */
6101         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6102         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6103         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6104         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6105         0x0000ffff                                          /* end                  */
6106     };
6107     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6108     HRESULT hr;
6109     DWORD color;
6110     float quad1[] =  {
6111         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6112          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6113         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6114          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6115     };
6116     float quad2[] =  {
6117          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6118          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6119          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6120          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6121     };
6122     float quad3[] =  {
6123         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6124          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6125         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6126          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6127     };
6128     float quad4[] =  {
6129          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6130          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6131          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6132          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6133     };
6134     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6135         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6136         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6137         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6138         D3DDECL_END()
6139     };
6140     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6141         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6142         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6143         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6144         D3DDECL_END()
6145     };
6146     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6147         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6148         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6149         D3DDECL_END()
6150     };
6151     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6152         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6153         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6154         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6155         D3DDECL_END()
6156     };
6157     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6158         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6159         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6160         D3DDECL_END()
6161     };
6162     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6163         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6164         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6165         D3DDECL_END()
6166     };
6167     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6168         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6169         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6170         D3DDECL_END()
6171     };
6172     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6173         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6174         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6175         D3DDECL_END()
6176     };
6177     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6178     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6179     unsigned int i;
6180     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6181     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6182
6183     struct vertex quad1_color[] =  {
6184        {-1.0,   -1.0,   0.1,    0x00ff8040},
6185        { 0.0,   -1.0,   0.1,    0x00ff8040},
6186        {-1.0,    0.0,   0.1,    0x00ff8040},
6187        { 0.0,    0.0,   0.1,    0x00ff8040}
6188     };
6189     struct vertex quad2_color[] =  {
6190        { 0.0,   -1.0,   0.1,    0x00ff8040},
6191        { 1.0,   -1.0,   0.1,    0x00ff8040},
6192        { 0.0,    0.0,   0.1,    0x00ff8040},
6193        { 1.0,    0.0,   0.1,    0x00ff8040}
6194     };
6195     struct vertex quad3_color[] =  {
6196        {-1.0,    0.0,   0.1,    0x00ff8040},
6197        { 0.0,    0.0,   0.1,    0x00ff8040},
6198        {-1.0,    1.0,   0.1,    0x00ff8040},
6199        { 0.0,    1.0,   0.1,    0x00ff8040}
6200     };
6201     float quad4_color[] =  {
6202          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6203          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6204          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6205          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6206     };
6207
6208     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6209     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6210     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6211     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6212     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6213     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6214     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6215     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6216
6217     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6218     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6219     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6220     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6221     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6222     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6223     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6225
6226     for(i = 1; i <= 3; i++) {
6227         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6228         if(i == 3) {
6229             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6230             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6231         } else if(i == 2){
6232             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6233             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6234         } else if(i == 1) {
6235             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6236             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6237         }
6238
6239         hr = IDirect3DDevice9_BeginScene(device);
6240         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6241         if(SUCCEEDED(hr))
6242         {
6243             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6244             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6245
6246             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6247             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6248             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6249             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6250
6251             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6252             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6253             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6254             if(i == 3 || i == 2) {
6255                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6256             } else if(i == 1) {
6257                 /* Succeeds or fails, depending on SW or HW vertex processing */
6258                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6259             }
6260
6261             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6262             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6263             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6264             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6265
6266             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6267             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6268             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6269             if(i == 3 || i == 2) {
6270                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6271             } else if(i == 1) {
6272                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6273             }
6274
6275             hr = IDirect3DDevice9_EndScene(device);
6276             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6277         }
6278
6279         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6280         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6281
6282         if(i == 3 || i == 2) {
6283             color = getPixelColor(device, 160, 360);
6284             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6285                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6286
6287             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6288             color = getPixelColor(device, 480, 360);
6289             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6290                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6291             color = getPixelColor(device, 160, 120);
6292             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6293             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6294                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6295
6296             color = getPixelColor(device, 480, 160);
6297             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6298         } else if(i == 1) {
6299             color = getPixelColor(device, 160, 360);
6300             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6301                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6302             color = getPixelColor(device, 480, 360);
6303             /* Accept the clear color as well in this case, since SW VP returns an error */
6304             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6305             color = getPixelColor(device, 160, 120);
6306             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6307                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6308             color = getPixelColor(device, 480, 160);
6309             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6310         }
6311
6312         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6313         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6314
6315         /* Now find out if the whole streams are re-read, or just the last active value for the
6316          * vertices is used.
6317          */
6318         hr = IDirect3DDevice9_BeginScene(device);
6319         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6320         if(SUCCEEDED(hr))
6321         {
6322             float quad1_modified[] =  {
6323                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6324                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6325                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6326                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6327             };
6328             float quad2_modified[] =  {
6329                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6330                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6331                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6332                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6333             };
6334
6335             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6336             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6337
6338             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6339             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6340             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6341             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6342
6343             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6344             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6345             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6346             if(i == 3 || i == 2) {
6347                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6348             } else if(i == 1) {
6349                 /* Succeeds or fails, depending on SW or HW vertex processing */
6350                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6351             }
6352
6353             hr = IDirect3DDevice9_EndScene(device);
6354             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6355         }
6356         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6357         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6358
6359         color = getPixelColor(device, 480, 350);
6360         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6361          * as well.
6362          *
6363          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6364          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6365          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6366          * refrast's result.
6367          *
6368          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6369          */
6370         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6371            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6372         color = getPixelColor(device, 160, 120);
6373
6374         IDirect3DDevice9_SetVertexShader(device, NULL);
6375         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6376
6377         IDirect3DVertexShader9_Release(swapped_shader);
6378     }
6379
6380     for(i = 1; i <= 3; i++) {
6381         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6382         if(i == 3) {
6383             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6384             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6385             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6386             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6387         } else if(i == 2){
6388             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6389             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6391             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392         } else if(i == 1) {
6393             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6394             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6395             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6396             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6397         }
6398
6399         hr = IDirect3DDevice9_BeginScene(device);
6400         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6401         if(SUCCEEDED(hr))
6402         {
6403             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6404             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6405             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6406             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6407             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6408             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6409
6410             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6411             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6412
6413             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6414             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6415             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6416             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6417             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6418             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6419
6420             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6421             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6422             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6423             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6424             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6425             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6426
6427             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6428             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6429             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6430             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6431
6432             hr = IDirect3DDevice9_EndScene(device);
6433             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6434         }
6435         IDirect3DDevice9_SetVertexShader(device, NULL);
6436         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6437
6438         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6439         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6440
6441         color = getPixelColor(device, 160, 360);
6442         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6443            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6444         color = getPixelColor(device, 480, 360);
6445         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6446            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6447         color = getPixelColor(device, 160, 120);
6448         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6449            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6450         color = getPixelColor(device, 480, 160);
6451         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6452            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6453
6454         IDirect3DVertexShader9_Release(texcoord_color_shader);
6455         IDirect3DVertexShader9_Release(color_color_shader);
6456     }
6457
6458     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6459     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6460     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6461     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6462
6463     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6464     IDirect3DVertexDeclaration9_Release(decl_color_color);
6465     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6466     IDirect3DVertexDeclaration9_Release(decl_color_float);
6467 }
6468
6469 static void srgbtexture_test(IDirect3DDevice9 *device)
6470 {
6471     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6472      * texture stage state to render a quad using that texture.  The resulting
6473      * color components should be 0x36 (~ 0.21), per this formula:
6474      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6475      * This is true where srgb_color > 0.04045.
6476      */
6477     IDirect3D9 *d3d = NULL;
6478     HRESULT hr;
6479     LPDIRECT3DTEXTURE9 texture = NULL;
6480     LPDIRECT3DSURFACE9 surface = NULL;
6481     D3DLOCKED_RECT lr;
6482     DWORD color;
6483     float quad[] = {
6484         -1.0,       1.0,       0.0,     0.0,    0.0,
6485          1.0,       1.0,       0.0,     1.0,    0.0,
6486         -1.0,      -1.0,       0.0,     0.0,    1.0,
6487          1.0,      -1.0,       0.0,     1.0,    1.0,
6488     };
6489
6490
6491     memset(&lr, 0, sizeof(lr));
6492     IDirect3DDevice9_GetDirect3D(device, &d3d);
6493     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6494                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6495                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6496         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6497         goto out;
6498     }
6499
6500     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6501                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6502                                         &texture, NULL);
6503     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6504     if(!texture) {
6505         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6506         goto out;
6507     }
6508     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6509     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6510
6511     fill_surface(surface, 0xff7f7f7f);
6512     IDirect3DSurface9_Release(surface);
6513
6514     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6515     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6516     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6517     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6518
6519     hr = IDirect3DDevice9_BeginScene(device);
6520     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6521     if(SUCCEEDED(hr))
6522     {
6523         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6524         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6525
6526         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6527         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6528
6529
6530         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6531         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6532
6533         hr = IDirect3DDevice9_EndScene(device);
6534         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6535     }
6536
6537     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6538     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6539     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6540     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6541
6542     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6543     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6544
6545     color = getPixelColor(device, 320, 240);
6546     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6547
6548 out:
6549     if(texture) IDirect3DTexture9_Release(texture);
6550     IDirect3D9_Release(d3d);
6551 }
6552
6553 static void shademode_test(IDirect3DDevice9 *device)
6554 {
6555     /* Render a quad and try all of the different fixed function shading models. */
6556     HRESULT hr;
6557     DWORD color0, color1;
6558     DWORD color0_gouraud = 0, color1_gouraud = 0;
6559     DWORD shademode = D3DSHADE_FLAT;
6560     DWORD primtype = D3DPT_TRIANGLESTRIP;
6561     LPVOID data = NULL;
6562     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6563     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6564     UINT i, j;
6565     struct vertex quad_strip[] =
6566     {
6567         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6568         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6569         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6570         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6571     };
6572     struct vertex quad_list[] =
6573     {
6574         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6575         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6576         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6577
6578         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6579         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6580         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6581     };
6582
6583     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6584                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6585     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6586     if (FAILED(hr)) goto bail;
6587
6588     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6589                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6590     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6591     if (FAILED(hr)) goto bail;
6592
6593     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6594     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6595
6596     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6597     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6598
6599     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6600     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6601     memcpy(data, quad_strip, sizeof(quad_strip));
6602     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6603     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6604
6605     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6606     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6607     memcpy(data, quad_list, sizeof(quad_list));
6608     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6609     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6610
6611     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6612      * the color fixups we have to do for FLAT shading will be dependent on that. */
6613     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6614     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6615
6616     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6617     for (j=0; j<2; j++) {
6618
6619         /* Inner loop just changes the D3DRS_SHADEMODE */
6620         for (i=0; i<3; i++) {
6621             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6622             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6623
6624             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6625             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6626
6627             hr = IDirect3DDevice9_BeginScene(device);
6628             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6629             if(SUCCEEDED(hr))
6630             {
6631                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6632                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6633
6634                 hr = IDirect3DDevice9_EndScene(device);
6635                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6636             }
6637
6638             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6639             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6640
6641             /* Sample two spots from the output */
6642             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6643             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6644             switch(shademode) {
6645                 case D3DSHADE_FLAT:
6646                     /* Should take the color of the first vertex of each triangle */
6647                     if (0)
6648                     {
6649                         /* This test depends on EXT_provoking_vertex being
6650                          * available. This extension is currently (20090810)
6651                          * not common enough to let the test fail if it isn't
6652                          * present. */
6653                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6654                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6655                     }
6656                     shademode = D3DSHADE_GOURAUD;
6657                     break;
6658                 case D3DSHADE_GOURAUD:
6659                     /* Should be an interpolated blend */
6660
6661                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6662                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6663                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6664                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6665
6666                     color0_gouraud = color0;
6667                     color1_gouraud = color1;
6668
6669                     shademode = D3DSHADE_PHONG;
6670                     break;
6671                 case D3DSHADE_PHONG:
6672                     /* Should be the same as GOURAUD, since no hardware implements this */
6673                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6674                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6675                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6676                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6677
6678                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6679                             color0_gouraud, color0);
6680                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6681                             color1_gouraud, color1);
6682                     break;
6683             }
6684         }
6685         /* Now, do it all over again with a TRIANGLELIST */
6686         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6687         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6688         primtype = D3DPT_TRIANGLELIST;
6689         shademode = D3DSHADE_FLAT;
6690     }
6691
6692 bail:
6693     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6694     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6695     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6696     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6697
6698     if (vb_strip)
6699         IDirect3DVertexBuffer9_Release(vb_strip);
6700     if (vb_list)
6701         IDirect3DVertexBuffer9_Release(vb_list);
6702 }
6703
6704
6705 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6706 {
6707     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6708      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6709      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6710      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6711      * 0.73
6712      *
6713      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6714      * so use shaders for this task
6715      */
6716     IDirect3DPixelShader9 *pshader;
6717     IDirect3DVertexShader9 *vshader;
6718     IDirect3D9 *d3d;
6719     DWORD vshader_code[] = {
6720         0xfffe0101,                                                             /* vs_1_1                       */
6721         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6722         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6723         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6724         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6725         0x0000ffff                                                              /* end                          */
6726     };
6727     DWORD pshader_code[] = {
6728         0xffff0101,                                                             /* ps_1_1                       */
6729         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6730         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6731         0x0000ffff                                                              /* end                          */
6732     };
6733     const float quad[] = {
6734        -1.0,   -1.0,    0.1,
6735         1.0,   -1.0,    0.1,
6736        -1.0,    1.0,    0.1,
6737         1.0,    1.0,    0.1
6738     };
6739     HRESULT hr;
6740     D3DCOLOR color;
6741
6742     IDirect3DDevice9_GetDirect3D(device, &d3d);
6743     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6744      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6745      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6746      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6747      * works
6748      */
6749     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6750                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6751                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6752         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6753         IDirect3D9_Release(d3d);
6754         return;
6755     }
6756     IDirect3D9_Release(d3d);
6757
6758     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6759     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6760
6761     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6762     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6763     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6764     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6765     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6766     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6767     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6768     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6769     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6770     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6771
6772     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6773     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6774     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6775     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6776     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6777     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6778     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6779     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6780     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6781     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6782
6783     hr = IDirect3DDevice9_BeginScene(device);
6784     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6785     if(SUCCEEDED(hr)) {
6786         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6787         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6788
6789         hr = IDirect3DDevice9_EndScene(device);
6790         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6791     }
6792
6793     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6794     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6795     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6796     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6797     IDirect3DPixelShader9_Release(pshader);
6798     IDirect3DVertexShader9_Release(vshader);
6799
6800     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6801     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6802     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6803     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6804
6805     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6806     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6807     color = getPixelColor(device, 160, 360);
6808     ok(color_match(color, 0x00808080, 1),
6809             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6810 }
6811
6812 static void alpha_test(IDirect3DDevice9 *device)
6813 {
6814     HRESULT hr;
6815     IDirect3DTexture9 *offscreenTexture;
6816     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6817     DWORD color;
6818
6819     struct vertex quad1[] =
6820     {
6821         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6822         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6823         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6824         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6825     };
6826     struct vertex quad2[] =
6827     {
6828         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6829         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6830         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6831         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6832     };
6833     static const float composite_quad[][5] = {
6834         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6835         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6836         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6837         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6838     };
6839
6840     /* Clear the render target with alpha = 0.5 */
6841     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6842     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6843
6844     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6845     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6846
6847     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6848     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6849     if(!backbuffer) {
6850         goto out;
6851     }
6852
6853     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6854     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6855     if(!offscreen) {
6856         goto out;
6857     }
6858
6859     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6860     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6861
6862     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6863     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6864     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6865     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6866     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6867     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6868     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6869     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6870     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6871     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6872
6873     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6874     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6875     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6876
6877         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6878         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6879         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6880         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6881         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6882         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6883         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6884
6885         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6886         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6887         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6888         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6889         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6890         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6891
6892         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6893          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6894          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6895         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6896         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6897         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6898         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6899
6900         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6901         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6902         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6903         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6904         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6905         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6906
6907         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6908         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6909         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6910         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6911         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6912         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6913
6914         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6915         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6916
6917         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6918          * Disable alpha blending for the final composition
6919          */
6920         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6921         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6922         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6923         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6924
6925         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6926         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6927         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6928         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6929         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6930         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6931
6932         hr = IDirect3DDevice9_EndScene(device);
6933         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6934     }
6935
6936     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6937
6938     color = getPixelColor(device, 160, 360);
6939     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6940        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6941
6942     color = getPixelColor(device, 160, 120);
6943     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6944        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6945
6946     color = getPixelColor(device, 480, 360);
6947     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6948        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6949
6950     color = getPixelColor(device, 480, 120);
6951     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6952        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6953
6954     out:
6955     /* restore things */
6956     if(backbuffer) {
6957         IDirect3DSurface9_Release(backbuffer);
6958     }
6959     if(offscreenTexture) {
6960         IDirect3DTexture9_Release(offscreenTexture);
6961     }
6962     if(offscreen) {
6963         IDirect3DSurface9_Release(offscreen);
6964     }
6965 }
6966
6967 struct vertex_shortcolor {
6968     float x, y, z;
6969     unsigned short r, g, b, a;
6970 };
6971 struct vertex_floatcolor {
6972     float x, y, z;
6973     float r, g, b, a;
6974 };
6975
6976 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6977 {
6978     HRESULT hr;
6979     BOOL s_ok, ub_ok, f_ok;
6980     DWORD color, size, i;
6981     void *data;
6982     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6983         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6984         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6985         D3DDECL_END()
6986     };
6987     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6988         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6989         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6990         D3DDECL_END()
6991     };
6992     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6993         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6994         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6995         D3DDECL_END()
6996     };
6997     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6998         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6999         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7000         D3DDECL_END()
7001     };
7002     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7003         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7004         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7005         D3DDECL_END()
7006     };
7007     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7008         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7009         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7010         D3DDECL_END()
7011     };
7012     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7013         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7014         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7015         D3DDECL_END()
7016     };
7017     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7018     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7019     IDirect3DVertexBuffer9 *vb, *vb2;
7020     struct vertex quad1[] =                             /* D3DCOLOR */
7021     {
7022         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7023         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7024         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7025         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7026     };
7027     struct vertex quad2[] =                             /* UBYTE4N */
7028     {
7029         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7030         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7031         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7032         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7033     };
7034     struct vertex_shortcolor quad3[] =                  /* short */
7035     {
7036         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7037         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7038         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7039         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7040     };
7041     struct vertex_floatcolor quad4[] =
7042     {
7043         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7044         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7045         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7046         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7047     };
7048     DWORD colors[] = {
7049         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7050         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7051         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7052         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7053         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7054         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7055         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7056         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7057         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7058         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7059         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7060         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7061         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7062         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7063         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7064         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7065     };
7066     float quads[] = {
7067         -1.0,   -1.0,     0.1,
7068         -1.0,    0.0,     0.1,
7069          0.0,   -1.0,     0.1,
7070          0.0,    0.0,     0.1,
7071
7072          0.0,   -1.0,     0.1,
7073          0.0,    0.0,     0.1,
7074          1.0,   -1.0,     0.1,
7075          1.0,    0.0,     0.1,
7076
7077          0.0,    0.0,     0.1,
7078          0.0,    1.0,     0.1,
7079          1.0,    0.0,     0.1,
7080          1.0,    1.0,     0.1,
7081
7082         -1.0,    0.0,     0.1,
7083         -1.0,    1.0,     0.1,
7084          0.0,    0.0,     0.1,
7085          0.0,    1.0,     0.1
7086     };
7087     struct tvertex quad_transformed[] = {
7088        {  90,    110,     0.1,      2.0,        0x00ffff00},
7089        { 570,    110,     0.1,      2.0,        0x00ffff00},
7090        {  90,    300,     0.1,      2.0,        0x00ffff00},
7091        { 570,    300,     0.1,      2.0,        0x00ffff00}
7092     };
7093     D3DCAPS9 caps;
7094
7095     memset(&caps, 0, sizeof(caps));
7096     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7097     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7098
7099     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7100     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7101
7102     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7103     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7104     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7105     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7106     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7107     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7108     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7109         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7110         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7111         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7112         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7113     } else {
7114         trace("D3DDTCAPS_UBYTE4N not supported\n");
7115         dcl_ubyte_2 = NULL;
7116         dcl_ubyte = NULL;
7117     }
7118     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7119     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7120     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7121     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7122
7123     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7124     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7125                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7126     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7127
7128     hr = IDirect3DDevice9_BeginScene(device);
7129     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7130     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7131     if(SUCCEEDED(hr)) {
7132         if(dcl_color) {
7133             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7134             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7135             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7136             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7137         }
7138
7139         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7140          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7141          * using software vertex processing. Doh!
7142          */
7143         if(dcl_ubyte) {
7144             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7145             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7146             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7147             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7148             ub_ok = SUCCEEDED(hr);
7149         }
7150
7151         if(dcl_short) {
7152             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7153             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7154             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7155             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7156             s_ok = SUCCEEDED(hr);
7157         }
7158
7159         if(dcl_float) {
7160             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7161             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7162             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7163             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7164             f_ok = SUCCEEDED(hr);
7165         }
7166
7167         hr = IDirect3DDevice9_EndScene(device);
7168         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7169     }
7170
7171     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7172     if(dcl_short) {
7173         color = getPixelColor(device, 480, 360);
7174         ok(color == 0x000000ff || !s_ok,
7175            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7176     }
7177     if(dcl_ubyte) {
7178         color = getPixelColor(device, 160, 120);
7179         ok(color == 0x0000ffff || !ub_ok,
7180            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7181     }
7182     if(dcl_color) {
7183         color = getPixelColor(device, 160, 360);
7184         ok(color == 0x00ffff00,
7185            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7186     }
7187     if(dcl_float) {
7188         color = getPixelColor(device, 480, 120);
7189         ok(color == 0x00ff0000 || !f_ok,
7190            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7191     }
7192
7193     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7194      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7195      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7196      * whether the immediate mode code works
7197      */
7198     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7199     hr = IDirect3DDevice9_BeginScene(device);
7200     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7201     if(SUCCEEDED(hr)) {
7202         if(dcl_color) {
7203             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7204             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7205             memcpy(data, quad1, sizeof(quad1));
7206             hr = IDirect3DVertexBuffer9_Unlock(vb);
7207             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7208             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7209             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7210             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7211             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7212             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7213             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7214         }
7215
7216         if(dcl_ubyte) {
7217             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7218             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7219             memcpy(data, quad2, sizeof(quad2));
7220             hr = IDirect3DVertexBuffer9_Unlock(vb);
7221             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7222             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7223             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7224             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7225             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7226             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7227             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7228                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7229             ub_ok = SUCCEEDED(hr);
7230         }
7231
7232         if(dcl_short) {
7233             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7234             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7235             memcpy(data, quad3, sizeof(quad3));
7236             hr = IDirect3DVertexBuffer9_Unlock(vb);
7237             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7238             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7239             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7240             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7241             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7242             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7243             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7244                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7245             s_ok = SUCCEEDED(hr);
7246         }
7247
7248         if(dcl_float) {
7249             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7250             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7251             memcpy(data, quad4, sizeof(quad4));
7252             hr = IDirect3DVertexBuffer9_Unlock(vb);
7253             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7254             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7255             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7256             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7257             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7258             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7259             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7260                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7261             f_ok = SUCCEEDED(hr);
7262         }
7263
7264         hr = IDirect3DDevice9_EndScene(device);
7265         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7266     }
7267
7268     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7269     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7270     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7271     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7272
7273     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7274     if(dcl_short) {
7275         color = getPixelColor(device, 480, 360);
7276         ok(color == 0x000000ff || !s_ok,
7277            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7278     }
7279     if(dcl_ubyte) {
7280         color = getPixelColor(device, 160, 120);
7281         ok(color == 0x0000ffff || !ub_ok,
7282            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7283     }
7284     if(dcl_color) {
7285         color = getPixelColor(device, 160, 360);
7286         ok(color == 0x00ffff00,
7287            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7288     }
7289     if(dcl_float) {
7290         color = getPixelColor(device, 480, 120);
7291         ok(color == 0x00ff0000 || !f_ok,
7292            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7293     }
7294
7295     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7296     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7297
7298     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7299     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7300     memcpy(data, quad_transformed, sizeof(quad_transformed));
7301     hr = IDirect3DVertexBuffer9_Unlock(vb);
7302     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7303
7304     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7305     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7306
7307     hr = IDirect3DDevice9_BeginScene(device);
7308     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7309     if(SUCCEEDED(hr)) {
7310         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7311         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7312         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7313         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7314
7315         hr = IDirect3DDevice9_EndScene(device);
7316         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7317     }
7318
7319     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7320     color = getPixelColor(device, 88, 108);
7321     ok(color == 0x000000ff,
7322        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7323     color = getPixelColor(device, 92, 108);
7324     ok(color == 0x000000ff,
7325        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7326     color = getPixelColor(device, 88, 112);
7327     ok(color == 0x000000ff,
7328        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7329     color = getPixelColor(device, 92, 112);
7330     ok(color == 0x00ffff00,
7331        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7332
7333     color = getPixelColor(device, 568, 108);
7334     ok(color == 0x000000ff,
7335        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7336     color = getPixelColor(device, 572, 108);
7337     ok(color == 0x000000ff,
7338        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7339     color = getPixelColor(device, 568, 112);
7340     ok(color == 0x00ffff00,
7341        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7342     color = getPixelColor(device, 572, 112);
7343     ok(color == 0x000000ff,
7344        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7345
7346     color = getPixelColor(device, 88, 298);
7347     ok(color == 0x000000ff,
7348        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7349     color = getPixelColor(device, 92, 298);
7350     ok(color == 0x00ffff00,
7351        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7352     color = getPixelColor(device, 88, 302);
7353     ok(color == 0x000000ff,
7354        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7355     color = getPixelColor(device, 92, 302);
7356     ok(color == 0x000000ff,
7357        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7358
7359     color = getPixelColor(device, 568, 298);
7360     ok(color == 0x00ffff00,
7361        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7362     color = getPixelColor(device, 572, 298);
7363     ok(color == 0x000000ff,
7364        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7365     color = getPixelColor(device, 568, 302);
7366     ok(color == 0x000000ff,
7367        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7368     color = getPixelColor(device, 572, 302);
7369     ok(color == 0x000000ff,
7370        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7371
7372     /* This test is pointless without those two declarations: */
7373     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7374         skip("color-ubyte switching test declarations aren't supported\n");
7375         goto out;
7376     }
7377
7378     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7379     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7380     memcpy(data, quads, sizeof(quads));
7381     hr = IDirect3DVertexBuffer9_Unlock(vb);
7382     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7383     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7384                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7385     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7386     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7387     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7388     memcpy(data, colors, sizeof(colors));
7389     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7390     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7391
7392     for(i = 0; i < 2; i++) {
7393         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7394         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7395
7396         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7397         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7398         if(i == 0) {
7399             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7400         } else {
7401             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7402         }
7403         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7404
7405         hr = IDirect3DDevice9_BeginScene(device);
7406         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7407         ub_ok = FALSE;
7408         if(SUCCEEDED(hr)) {
7409             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7410             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7411             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7412             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7413                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7414             ub_ok = SUCCEEDED(hr);
7415
7416             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7417             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7418             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7419             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7420
7421             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7422             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7423             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7424             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7425                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7426             ub_ok = (SUCCEEDED(hr) && ub_ok);
7427
7428             hr = IDirect3DDevice9_EndScene(device);
7429             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7430         }
7431
7432         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7433         if(i == 0) {
7434             color = getPixelColor(device, 480, 360);
7435             ok(color == 0x00ff0000,
7436                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7437             color = getPixelColor(device, 160, 120);
7438             ok(color == 0x00ffffff,
7439                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7440             color = getPixelColor(device, 160, 360);
7441             ok(color == 0x000000ff || !ub_ok,
7442                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7443             color = getPixelColor(device, 480, 120);
7444             ok(color == 0x000000ff || !ub_ok,
7445                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7446         } else {
7447             color = getPixelColor(device, 480, 360);
7448             ok(color == 0x000000ff,
7449                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7450             color = getPixelColor(device, 160, 120);
7451             ok(color == 0x00ffffff,
7452                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7453             color = getPixelColor(device, 160, 360);
7454             ok(color == 0x00ff0000 || !ub_ok,
7455                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7456             color = getPixelColor(device, 480, 120);
7457             ok(color == 0x00ff0000 || !ub_ok,
7458                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7459         }
7460     }
7461
7462     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7463     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7464     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7465     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7466     IDirect3DVertexBuffer9_Release(vb2);
7467
7468     out:
7469     IDirect3DVertexBuffer9_Release(vb);
7470     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7471     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7472     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7473     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7474     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7475     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7476     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7477 }
7478
7479 struct vertex_float16color {
7480     float x, y, z;
7481     DWORD c1, c2;
7482 };
7483
7484 static void test_vshader_float16(IDirect3DDevice9 *device)
7485 {
7486     HRESULT hr;
7487     DWORD color;
7488     void *data;
7489     static const D3DVERTEXELEMENT9 decl_elements[] = {
7490         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7491         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7492         D3DDECL_END()
7493     };
7494     IDirect3DVertexDeclaration9 *vdecl = NULL;
7495     IDirect3DVertexBuffer9 *buffer = NULL;
7496     IDirect3DVertexShader9 *shader;
7497     DWORD shader_code[] = {
7498         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7499         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7500         0x90e40001, 0x0000ffff
7501     };
7502     struct vertex_float16color quad[] = {
7503         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7504         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7505         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7506         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7507
7508         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7509         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7510         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7511         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7512
7513         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7514         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7515         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7516         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7517
7518         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7519         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7520         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7521         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7522     };
7523
7524     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7525     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7526
7527     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7528     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7529     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7530     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7531     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7532     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7533
7534     hr = IDirect3DDevice9_BeginScene(device);
7535     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7536     if(SUCCEEDED(hr)) {
7537         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7538         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7539         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7540         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7541         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7542         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7543         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7544         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7545         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7546         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7547
7548         hr = IDirect3DDevice9_EndScene(device);
7549         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7550     }
7551     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7552     color = getPixelColor(device, 480, 360);
7553     ok(color == 0x00ff0000,
7554        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7555     color = getPixelColor(device, 160, 120);
7556     ok(color == 0x00000000,
7557        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7558     color = getPixelColor(device, 160, 360);
7559     ok(color == 0x0000ff00,
7560        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7561     color = getPixelColor(device, 480, 120);
7562     ok(color == 0x000000ff,
7563        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7564
7565     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7566     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7567
7568     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7569                                              D3DPOOL_MANAGED, &buffer, NULL);
7570     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7571     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7572     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7573     memcpy(data, quad, sizeof(quad));
7574     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7575     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7576     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7577     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7578
7579     hr = IDirect3DDevice9_BeginScene(device);
7580     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7581     if(SUCCEEDED(hr)) {
7582             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7583             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7584             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7585             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7586             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7587             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7588             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7589             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7590
7591             hr = IDirect3DDevice9_EndScene(device);
7592             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7593     }
7594
7595     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7596     color = getPixelColor(device, 480, 360);
7597     ok(color == 0x00ff0000,
7598        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7599     color = getPixelColor(device, 160, 120);
7600     ok(color == 0x00000000,
7601        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7602     color = getPixelColor(device, 160, 360);
7603     ok(color == 0x0000ff00,
7604        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7605     color = getPixelColor(device, 480, 120);
7606     ok(color == 0x000000ff,
7607        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7608
7609     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7610     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7611     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7612     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7613     IDirect3DDevice9_SetVertexShader(device, NULL);
7614     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7615
7616     IDirect3DVertexDeclaration9_Release(vdecl);
7617     IDirect3DVertexShader9_Release(shader);
7618     IDirect3DVertexBuffer9_Release(buffer);
7619 }
7620
7621 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7622 {
7623     D3DCAPS9 caps;
7624     IDirect3DTexture9 *texture;
7625     HRESULT hr;
7626     D3DLOCKED_RECT rect;
7627     unsigned int x, y;
7628     DWORD *dst, color;
7629     const float quad[] = {
7630         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7631          1.0,   -1.0,   0.1,    1.2,   -0.2,
7632         -1.0,    1.0,   0.1,   -0.2,    1.2,
7633          1.0,    1.0,   0.1,    1.2,    1.2
7634     };
7635     memset(&caps, 0, sizeof(caps));
7636
7637     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7638     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7639     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7640         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7641         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7642            "Card has conditional NP2 support without power of two restriction set\n");
7643         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7644         return;
7645     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7646         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7647         return;
7648     }
7649
7650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7651     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7652
7653     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7654     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7655
7656     memset(&rect, 0, sizeof(rect));
7657     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7658     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7659     for(y = 0; y < 10; y++) {
7660         for(x = 0; x < 10; x++) {
7661             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7662             if(x == 0 || x == 9 || y == 0 || y == 9) {
7663                 *dst = 0x00ff0000;
7664             } else {
7665                 *dst = 0x000000ff;
7666             }
7667         }
7668     }
7669     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7670     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7671
7672     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7673     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7674     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7675     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7676     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7677     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7678     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7679     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7680
7681     hr = IDirect3DDevice9_BeginScene(device);
7682     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7683     if(SUCCEEDED(hr)) {
7684         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7685         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7686
7687         hr = IDirect3DDevice9_EndScene(device);
7688         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7689     }
7690
7691     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7692
7693     color = getPixelColor(device,    1,  1);
7694     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7695     color = getPixelColor(device, 639, 479);
7696     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7697
7698     color = getPixelColor(device, 135, 101);
7699     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7700     color = getPixelColor(device, 140, 101);
7701     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7702     color = getPixelColor(device, 135, 105);
7703     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7704     color = getPixelColor(device, 140, 105);
7705     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7706
7707     color = getPixelColor(device, 135, 376);
7708     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7709     color = getPixelColor(device, 140, 376);
7710     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7711     color = getPixelColor(device, 135, 379);
7712     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7713     color = getPixelColor(device, 140, 379);
7714     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7715
7716     color = getPixelColor(device, 500, 101);
7717     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7718     color = getPixelColor(device, 504, 101);
7719     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7720     color = getPixelColor(device, 500, 105);
7721     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7722     color = getPixelColor(device, 504, 105);
7723     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7724
7725     color = getPixelColor(device, 500, 376);
7726     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7727     color = getPixelColor(device, 504, 376);
7728     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7729     color = getPixelColor(device, 500, 380);
7730     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7731     color = getPixelColor(device, 504, 380);
7732     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7733
7734     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7735     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7736     IDirect3DTexture9_Release(texture);
7737 }
7738
7739 static void vFace_register_test(IDirect3DDevice9 *device)
7740 {
7741     HRESULT hr;
7742     DWORD color;
7743     const DWORD shader_code[] = {
7744         0xffff0300,                                                             /* ps_3_0                     */
7745         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7746         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7747         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7748         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7749         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7750         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7751         0x0000ffff                                                              /* END                        */
7752     };
7753     IDirect3DPixelShader9 *shader;
7754     IDirect3DTexture9 *texture;
7755     IDirect3DSurface9 *surface, *backbuffer;
7756     const float quad[] = {
7757         -1.0,   -1.0,   0.1,
7758          1.0,   -1.0,   0.1,
7759         -1.0,    0.0,   0.1,
7760
7761          1.0,   -1.0,   0.1,
7762          1.0,    0.0,   0.1,
7763         -1.0,    0.0,   0.1,
7764
7765         -1.0,    0.0,   0.1,
7766         -1.0,    1.0,   0.1,
7767          1.0,    0.0,   0.1,
7768
7769          1.0,    0.0,   0.1,
7770         -1.0,    1.0,   0.1,
7771          1.0,    1.0,   0.1,
7772     };
7773     const float blit[] = {
7774          0.0,   -1.0,   0.1,    0.0,    0.0,
7775          1.0,   -1.0,   0.1,    1.0,    0.0,
7776          0.0,    1.0,   0.1,    0.0,    1.0,
7777          1.0,    1.0,   0.1,    1.0,    1.0,
7778     };
7779
7780     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7781     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7782     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7783     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7784     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7785     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7786     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7787     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7788     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7789     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7790     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7791     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7792
7793     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7794     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7795
7796     hr = IDirect3DDevice9_BeginScene(device);
7797     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7798     if(SUCCEEDED(hr)) {
7799         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7800         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7801         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7802         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7803         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7804         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7805         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7806         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7807         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7809         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7810
7811         /* Blit the texture onto the back buffer to make it visible */
7812         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7813         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7814         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7815         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7816         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7817         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7818         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7819         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7820         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7821         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7822
7823         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7824         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7825
7826         hr = IDirect3DDevice9_EndScene(device);
7827         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7828     }
7829
7830     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7831     color = getPixelColor(device, 160, 360);
7832     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7833     color = getPixelColor(device, 160, 120);
7834     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7835     color = getPixelColor(device, 480, 360);
7836     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7837     color = getPixelColor(device, 480, 120);
7838     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7839
7840     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7841     IDirect3DDevice9_SetTexture(device, 0, NULL);
7842     IDirect3DPixelShader9_Release(shader);
7843     IDirect3DSurface9_Release(surface);
7844     IDirect3DSurface9_Release(backbuffer);
7845     IDirect3DTexture9_Release(texture);
7846 }
7847
7848 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7849 {
7850     HRESULT hr;
7851     DWORD color;
7852     int i;
7853     D3DCAPS9 caps;
7854     BOOL L6V5U5_supported = FALSE;
7855     IDirect3DTexture9 *tex1, *tex2;
7856     D3DLOCKED_RECT locked_rect;
7857
7858     static const float quad[][7] = {
7859         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7860         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7861         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7862         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7863     };
7864
7865     static const D3DVERTEXELEMENT9 decl_elements[] = {
7866         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7867         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7868         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7869         D3DDECL_END()
7870     };
7871
7872     /* use asymmetric matrix to test loading */
7873     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7874     float scale, offset;
7875
7876     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7877     IDirect3DTexture9           *texture            = NULL;
7878
7879     memset(&caps, 0, sizeof(caps));
7880     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7881     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7882     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7883         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7884         return;
7885     } else {
7886         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7887          * They report that it is not supported, but after that bump mapping works properly. So just test
7888          * if the format is generally supported, and check the BUMPENVMAP flag
7889          */
7890         IDirect3D9 *d3d9;
7891
7892         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7893         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7894                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7895         L6V5U5_supported = SUCCEEDED(hr);
7896         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7897                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7898         IDirect3D9_Release(d3d9);
7899         if(FAILED(hr)) {
7900             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7901             return;
7902         }
7903     }
7904
7905     /* Generate the textures */
7906     generate_bumpmap_textures(device);
7907
7908     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7909     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7910     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7911     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7912     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7913     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7914     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7915     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7916
7917     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7918     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7919     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7920     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7921     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7922     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7923
7924     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7925     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7926     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7927     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7928     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7929     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7930
7931     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7932     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933
7934     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7935     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7936
7937     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7938     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7939
7940
7941     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7942     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7943     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7944     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7945
7946     hr = IDirect3DDevice9_BeginScene(device);
7947     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7948
7949     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7950     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7951
7952     hr = IDirect3DDevice9_EndScene(device);
7953     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7954
7955     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7956     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7957
7958     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7959      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7960      * But since testing the color match is not the purpose of the test don't be too picky
7961      */
7962     color = getPixelColor(device, 320-32, 240);
7963     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7964     color = getPixelColor(device, 320+32, 240);
7965     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7966     color = getPixelColor(device, 320, 240-32);
7967     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7968     color = getPixelColor(device, 320, 240+32);
7969     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7970     color = getPixelColor(device, 320, 240);
7971     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7972     color = getPixelColor(device, 320+32, 240+32);
7973     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7974     color = getPixelColor(device, 320-32, 240+32);
7975     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7976     color = getPixelColor(device, 320+32, 240-32);
7977     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7978     color = getPixelColor(device, 320-32, 240-32);
7979     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7980
7981     for(i = 0; i < 2; i++) {
7982         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7983         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7984         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7985         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7986         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7987         IDirect3DTexture9_Release(texture); /* To destroy it */
7988     }
7989
7990     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7991         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7992         goto cleanup;
7993     }
7994     if(L6V5U5_supported == FALSE) {
7995         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7996         goto cleanup;
7997     }
7998
7999     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8000     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8001     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8002      * would only make this test more complicated
8003      */
8004     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8005     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8006     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8007     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8008
8009     memset(&locked_rect, 0, sizeof(locked_rect));
8010     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8011     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8012     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8013     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8014     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8015
8016     memset(&locked_rect, 0, sizeof(locked_rect));
8017     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8018     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8019     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8020     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8021     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8022
8023     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8025     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8026     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8027
8028     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8029     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8030     scale = 2.0;
8031     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8032     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8033     offset = 0.1;
8034     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8035     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8036
8037     hr = IDirect3DDevice9_BeginScene(device);
8038     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8039     if(SUCCEEDED(hr)) {
8040         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8041         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8042         hr = IDirect3DDevice9_EndScene(device);
8043         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8044     }
8045
8046     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8047     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8048     color = getPixelColor(device, 320, 240);
8049     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8050      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8051      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8052      */
8053     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8054
8055     /* Check a result scale factor > 1.0 */
8056     scale = 10;
8057     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8058     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8059     offset = 10;
8060     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8061     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8062
8063     hr = IDirect3DDevice9_BeginScene(device);
8064     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8065     if(SUCCEEDED(hr)) {
8066         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8067         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8068         hr = IDirect3DDevice9_EndScene(device);
8069         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8070     }
8071     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8072     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8073     color = getPixelColor(device, 320, 240);
8074     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8075
8076     /* Check clamping in the scale factor calculation */
8077     scale = 1000;
8078     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8079     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8080     offset = -1;
8081     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8082     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8083
8084     hr = IDirect3DDevice9_BeginScene(device);
8085     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8086     if(SUCCEEDED(hr)) {
8087         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8088         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8089         hr = IDirect3DDevice9_EndScene(device);
8090         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8091     }
8092     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8093     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8094     color = getPixelColor(device, 320, 240);
8095     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8096
8097     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8098     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8099     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8100     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8101
8102     IDirect3DTexture9_Release(tex1);
8103     IDirect3DTexture9_Release(tex2);
8104
8105 cleanup:
8106     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8107     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8108     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8109     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8110
8111     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8112     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8113     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8114 }
8115
8116 static void stencil_cull_test(IDirect3DDevice9 *device) {
8117     HRESULT hr;
8118     IDirect3DSurface9 *depthstencil = NULL;
8119     D3DSURFACE_DESC desc;
8120     float quad1[] = {
8121         -1.0,   -1.0,   0.1,
8122          0.0,   -1.0,   0.1,
8123         -1.0,    0.0,   0.1,
8124          0.0,    0.0,   0.1,
8125     };
8126     float quad2[] = {
8127          0.0,   -1.0,   0.1,
8128          1.0,   -1.0,   0.1,
8129          0.0,    0.0,   0.1,
8130          1.0,    0.0,   0.1,
8131     };
8132     float quad3[] = {
8133         0.0,    0.0,   0.1,
8134         1.0,    0.0,   0.1,
8135         0.0,    1.0,   0.1,
8136         1.0,    1.0,   0.1,
8137     };
8138     float quad4[] = {
8139         -1.0,    0.0,   0.1,
8140          0.0,    0.0,   0.1,
8141         -1.0,    1.0,   0.1,
8142          0.0,    1.0,   0.1,
8143     };
8144     struct vertex painter[] = {
8145        {-1.0,   -1.0,   0.0,    0x00000000},
8146        { 1.0,   -1.0,   0.0,    0x00000000},
8147        {-1.0,    1.0,   0.0,    0x00000000},
8148        { 1.0,    1.0,   0.0,    0x00000000},
8149     };
8150     WORD indices_cw[]  = {0, 1, 3};
8151     WORD indices_ccw[] = {0, 2, 3};
8152     unsigned int i;
8153     DWORD color;
8154
8155     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8156     if(depthstencil == NULL) {
8157         skip("No depth stencil buffer\n");
8158         return;
8159     }
8160     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8161     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8162     IDirect3DSurface9_Release(depthstencil);
8163     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8164         skip("No 4 or 8 bit stencil surface\n");
8165         return;
8166     }
8167
8168     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8169     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8170     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8171
8172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8173     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8174     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8175     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8176     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8177     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8178     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8179     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8180
8181     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8182     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8183     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8184     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8185     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8186     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8187
8188     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8189     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8190     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8191     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8192
8193     /* First pass: Fill the stencil buffer with some values... */
8194     hr = IDirect3DDevice9_BeginScene(device);
8195     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8196     if(SUCCEEDED(hr))
8197     {
8198         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8199         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8200         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8201                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8202         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8203                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8204
8205         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8206         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8207         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8208         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8209         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8210                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8211         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8212                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8213
8214         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8215         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8216         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8217                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8218         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8219                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8220
8221         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8222         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8223         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8224                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8225         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8226                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8227
8228         hr = IDirect3DDevice9_EndScene(device);
8229         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8230     }
8231
8232     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8233     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8234     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8235     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8236     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8237     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8238     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8239     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8240     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8241     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8242     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8243     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8244     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8245
8246     /* 2nd pass: Make the stencil values visible */
8247     hr = IDirect3DDevice9_BeginScene(device);
8248     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8249     if(SUCCEEDED(hr))
8250     {
8251         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8252         for(i = 0; i < 16; i++) {
8253             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8254             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8255
8256             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8257             painter[1].diffuse = (i * 16);
8258             painter[2].diffuse = (i * 16);
8259             painter[3].diffuse = (i * 16);
8260             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8261             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8262         }
8263         hr = IDirect3DDevice9_EndScene(device);
8264         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8265     }
8266
8267     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8268     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8269
8270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8272
8273     color = getPixelColor(device, 160, 420);
8274     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8275     color = getPixelColor(device, 160, 300);
8276     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8277
8278     color = getPixelColor(device, 480, 420);
8279     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8280     color = getPixelColor(device, 480, 300);
8281     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8282
8283     color = getPixelColor(device, 160, 180);
8284     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8285     color = getPixelColor(device, 160, 60);
8286     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8287
8288     color = getPixelColor(device, 480, 180);
8289     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8290     color = getPixelColor(device, 480, 60);
8291     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8292 }
8293
8294 static void vpos_register_test(IDirect3DDevice9 *device)
8295 {
8296     HRESULT hr;
8297     DWORD color;
8298     const DWORD shader_code[] = {
8299     0xffff0300,                                                             /* ps_3_0                     */
8300     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8301     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8302     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8303     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8304     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8305     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8306     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8307     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8308     0x0000ffff                                                              /* end                        */
8309     };
8310     const DWORD shader_frac_code[] = {
8311     0xffff0300,                                                             /* ps_3_0                     */
8312     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8313     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8314     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8315     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8316     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8317     0x0000ffff                                                              /* end                        */
8318     };
8319     IDirect3DPixelShader9 *shader, *shader_frac;
8320     IDirect3DSurface9 *surface = NULL, *backbuffer;
8321     const float quad[] = {
8322         -1.0,   -1.0,   0.1,    0.0,    0.0,
8323          1.0,   -1.0,   0.1,    1.0,    0.0,
8324         -1.0,    1.0,   0.1,    0.0,    1.0,
8325          1.0,    1.0,   0.1,    1.0,    1.0,
8326     };
8327     D3DLOCKED_RECT lr;
8328     float constant[4] = {1.0, 0.0, 320, 240};
8329     DWORD *pos;
8330
8331     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8332     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8333     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8334     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8335     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8336     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8337     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8338     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8339     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8340     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8341     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8342     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8343
8344     hr = IDirect3DDevice9_BeginScene(device);
8345     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8346     if(SUCCEEDED(hr)) {
8347         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8348         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8349         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8350         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8351         hr = IDirect3DDevice9_EndScene(device);
8352         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8353     }
8354
8355     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8356     /* This has to be pixel exact */
8357     color = getPixelColor(device, 319, 239);
8358     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8359     color = getPixelColor(device, 320, 239);
8360     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8361     color = getPixelColor(device, 319, 240);
8362     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8363     color = getPixelColor(device, 320, 240);
8364     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8365
8366     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8367                                              &surface, NULL);
8368     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8369     hr = IDirect3DDevice9_BeginScene(device);
8370     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8371     if(SUCCEEDED(hr)) {
8372         constant[2] = 16; constant[3] = 16;
8373         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8374         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8375         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8376         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8377         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8378         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8379         hr = IDirect3DDevice9_EndScene(device);
8380         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8381     }
8382     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8383     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8384
8385     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8386     color = *pos & 0x00ffffff;
8387     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8388     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8389     color = *pos & 0x00ffffff;
8390     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8391     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8392     color = *pos & 0x00ffffff;
8393     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8394     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8395     color = *pos & 0x00ffffff;
8396     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8397
8398     hr = IDirect3DSurface9_UnlockRect(surface);
8399     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8400
8401     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8402      * have full control over the multisampling setting inside this test
8403      */
8404     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8405     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8406     hr = IDirect3DDevice9_BeginScene(device);
8407     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8408     if(SUCCEEDED(hr)) {
8409         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8410         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8411         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8412         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8413         hr = IDirect3DDevice9_EndScene(device);
8414         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8415     }
8416     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8417     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8418
8419     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8420     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8421
8422     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8423     color = *pos & 0x00ffffff;
8424     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8425
8426     hr = IDirect3DSurface9_UnlockRect(surface);
8427     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8428
8429     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8430     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8431     IDirect3DPixelShader9_Release(shader);
8432     IDirect3DPixelShader9_Release(shader_frac);
8433     if(surface) IDirect3DSurface9_Release(surface);
8434     IDirect3DSurface9_Release(backbuffer);
8435 }
8436
8437 static void pointsize_test(IDirect3DDevice9 *device)
8438 {
8439     HRESULT hr;
8440     D3DCAPS9 caps;
8441     D3DMATRIX matrix;
8442     D3DMATRIX identity;
8443     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8444     DWORD color;
8445     IDirect3DTexture9 *tex1, *tex2;
8446     D3DLOCKED_RECT lr;
8447     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8448                                 0x00000000, 0x00000000};
8449     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8450                                 0x00000000, 0x0000ff00};
8451
8452     const float vertices[] = {
8453         64,     64,     0.1,
8454         128,    64,     0.1,
8455         192,    64,     0.1,
8456         256,    64,     0.1,
8457         320,    64,     0.1,
8458         384,    64,     0.1,
8459         448,    64,     0.1,
8460         512,    64,     0.1,
8461         576,    64,     0.1,
8462     };
8463
8464     /* 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 */
8465     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;
8466     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;
8467     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;
8468     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;
8469
8470     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;
8471     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;
8472     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;
8473     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;
8474
8475     memset(&caps, 0, sizeof(caps));
8476     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8477     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8478     if(caps.MaxPointSize < 32.0) {
8479         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8480         return;
8481     }
8482
8483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8484     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8485     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8486     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8487     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8488     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8489     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8490     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8491
8492     hr = IDirect3DDevice9_BeginScene(device);
8493     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8494     if(SUCCEEDED(hr)) {
8495         ptsize = 16.0;
8496         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8497         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8498         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8499         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8500
8501         ptsize = 32.0;
8502         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8503         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8504         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8505         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8506
8507         ptsize = 31.5;
8508         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8509         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8510         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8511         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8512
8513         if(caps.MaxPointSize >= 64.0) {
8514             ptsize = 64.0;
8515             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8516             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8517             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8518             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8519
8520             ptsize = 63.75;
8521             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8522             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8523             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8524             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8525         }
8526
8527         ptsize = 1.0;
8528         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8529         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8530         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8531         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8532
8533         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8534         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8535         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8536         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8537
8538         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8539         ptsize = 16.0;
8540         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8541         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8542         ptsize = 1.0;
8543         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8544         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8545         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8546         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8547
8548         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8549          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8550          */
8551         ptsize = 4.0;
8552         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8553         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8554         ptsize = 16.0;
8555         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8556         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8557         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8558         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8559
8560         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8561         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8562
8563         /* pointsize < pointsize_min < pointsize_max?
8564          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8565          */
8566         ptsize = 1.0;
8567         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8568         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8569         ptsize = 16.0;
8570         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8571         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8573         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8574
8575         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8576         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8577
8578         hr = IDirect3DDevice9_EndScene(device);
8579         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8580     }
8581     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8582     color = getPixelColor(device, 64-9, 64-9);
8583     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8584     color = getPixelColor(device, 64-8, 64-8);
8585     ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8586     color = getPixelColor(device, 64-7, 64-7);
8587     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8588     color = getPixelColor(device, 64+7, 64+7);
8589     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8590     color = getPixelColor(device, 64+8, 64+8);
8591     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8592     color = getPixelColor(device, 64+9, 64+9);
8593     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8594
8595     color = getPixelColor(device, 128-17, 64-17);
8596     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8597     color = getPixelColor(device, 128-16, 64-16);
8598     ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8599     color = getPixelColor(device, 128-15, 64-15);
8600     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8601     color = getPixelColor(device, 128+15, 64+15);
8602     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8603     color = getPixelColor(device, 128+16, 64+16);
8604     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8605     color = getPixelColor(device, 128+17, 64+17);
8606     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8607
8608     color = getPixelColor(device, 192-17, 64-17);
8609     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8610     color = getPixelColor(device, 192-16, 64-16);
8611     todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8612     color = getPixelColor(device, 192-15, 64-15);
8613     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8614     color = getPixelColor(device, 192+15, 64+15);
8615     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8616     color = getPixelColor(device, 192+16, 64+16);
8617     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8618     color = getPixelColor(device, 192+17, 64+17);
8619     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8620
8621     if(caps.MaxPointSize >= 64.0) {
8622         color = getPixelColor(device, 256-33, 64-33);
8623         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8624         color = getPixelColor(device, 256-32, 64-32);
8625         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8626         color = getPixelColor(device, 256-31, 64-31);
8627         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8628         color = getPixelColor(device, 256+31, 64+31);
8629         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8630         color = getPixelColor(device, 256+32, 64+32);
8631         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8632         color = getPixelColor(device, 256+33, 64+33);
8633         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8634
8635         color = getPixelColor(device, 384-33, 64-33);
8636         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8637         color = getPixelColor(device, 384-32, 64-32);
8638         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8639         color = getPixelColor(device, 384-31, 64-31);
8640         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8641         color = getPixelColor(device, 384+31, 64+31);
8642         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8643         color = getPixelColor(device, 384+32, 64+32);
8644         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8645         color = getPixelColor(device, 384+33, 64+33);
8646         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8647     }
8648
8649     color = getPixelColor(device, 320-1, 64-1);
8650     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8651     color = getPixelColor(device, 320-0, 64-0);
8652     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8653     color = getPixelColor(device, 320+1, 64+1);
8654     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8655
8656     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8657     color = getPixelColor(device, 448-4, 64-4);
8658     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8659     color = getPixelColor(device, 448+4, 64+4);
8660     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8661
8662     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8663     color = getPixelColor(device, 512-4, 64-4);
8664     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8665     color = getPixelColor(device, 512+4, 64+4);
8666     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8667
8668     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8669      * Don't be overly picky - just show that the point is bigger than 1 pixel
8670      */
8671     color = getPixelColor(device, 576-4, 64-4);
8672     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8673     color = getPixelColor(device, 576+4, 64+4);
8674     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8675
8676     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8677      * generates texture coordinates for the point(result: Yes, it does)
8678      *
8679      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8680      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8681      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8682      */
8683     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8684     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8685
8686     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8687     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8688     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8689     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8690     memset(&lr, 0, sizeof(lr));
8691     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8692     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8693     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8694     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8695     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8696     memset(&lr, 0, sizeof(lr));
8697     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8698     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8699     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8700     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8701     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8702     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8703     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8704     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8705     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8706     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8707     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8708     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8709     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8710     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8711     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8712     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8713     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8714     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8715     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8716
8717     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8718     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8719     ptsize = 32.0;
8720     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8721     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8722
8723     hr = IDirect3DDevice9_BeginScene(device);
8724     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8725     if(SUCCEEDED(hr))
8726     {
8727         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8728         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8729         hr = IDirect3DDevice9_EndScene(device);
8730         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8731     }
8732
8733     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8734     color = getPixelColor(device, 64-4, 64-4);
8735     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8736     color = getPixelColor(device, 64-4, 64+4);
8737     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8738     color = getPixelColor(device, 64+4, 64+4);
8739     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8740     color = getPixelColor(device, 64+4, 64-4);
8741     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8742
8743     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8744     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8745     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8746     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8747     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8748     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8749     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8750     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8751     IDirect3DTexture9_Release(tex1);
8752     IDirect3DTexture9_Release(tex2);
8753
8754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8755     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8757     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8758     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8759     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8760 }
8761
8762 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8763 {
8764     HRESULT hr;
8765     IDirect3DPixelShader9 *ps;
8766     IDirect3DTexture9 *tex1, *tex2;
8767     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8768     D3DCAPS9 caps;
8769     DWORD color;
8770     DWORD shader_code[] = {
8771     0xffff0300,                                                             /* ps_3_0             */
8772     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8773     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8774     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8775     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8776     0x0000ffff                                                              /* END                */
8777     };
8778     float quad[] = {
8779        -1.0,   -1.0,    0.1,
8780         1.0,   -1.0,    0.1,
8781        -1.0,    1.0,    0.1,
8782         1.0,    1.0,    0.1,
8783     };
8784     float texquad[] = {
8785        -1.0,   -1.0,    0.1,    0.0,    0.0,
8786         0.0,   -1.0,    0.1,    1.0,    0.0,
8787        -1.0,    1.0,    0.1,    0.0,    1.0,
8788         0.0,    1.0,    0.1,    1.0,    1.0,
8789
8790         0.0,   -1.0,    0.1,    0.0,    0.0,
8791         1.0,   -1.0,    0.1,    1.0,    0.0,
8792         0.0,    1.0,    0.1,    0.0,    1.0,
8793         1.0,    1.0,    0.1,    1.0,    1.0,
8794     };
8795
8796     memset(&caps, 0, sizeof(caps));
8797     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8798     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8799     if(caps.NumSimultaneousRTs < 2) {
8800         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8801         return;
8802     }
8803
8804     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8805     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8806
8807     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8808     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8809     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8810     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8811     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8812     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8813
8814     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8815     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8816     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8817     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8818     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8819     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8820
8821     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8822     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8823     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8824     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8825     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8826     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8827     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8828     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8829
8830     hr = IDirect3DDevice9_BeginScene(device);
8831     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8832     if(SUCCEEDED(hr)) {
8833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8834         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8835
8836         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8837         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8838         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8839         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8840         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8841         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8842         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8843         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8844
8845         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8846         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8848         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8849
8850         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8851         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8852         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8853         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8854
8855         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8856         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8857
8858         hr = IDirect3DDevice9_EndScene(device);
8859         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8860     }
8861
8862     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8863     color = getPixelColor(device, 160, 240);
8864     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8865     color = getPixelColor(device, 480, 240);
8866     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8867
8868     IDirect3DPixelShader9_Release(ps);
8869     IDirect3DTexture9_Release(tex1);
8870     IDirect3DTexture9_Release(tex2);
8871     IDirect3DSurface9_Release(surf1);
8872     IDirect3DSurface9_Release(surf2);
8873     IDirect3DSurface9_Release(backbuf);
8874 }
8875
8876 struct formats {
8877     const char *fmtName;
8878     D3DFORMAT textureFormat;
8879     DWORD resultColorBlending;
8880     DWORD resultColorNoBlending;
8881 };
8882
8883 const struct formats test_formats[] = {
8884   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8885   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8886   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8887   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8888   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8889   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8890   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8891   { NULL, 0 }
8892 };
8893
8894 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8895 {
8896     HRESULT hr;
8897     IDirect3DTexture9 *offscreenTexture = NULL;
8898     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8899     IDirect3D9 *d3d = NULL;
8900     DWORD color;
8901     DWORD r0, g0, b0, r1, g1, b1;
8902     int fmt_index;
8903
8904     static const float quad[][5] = {
8905         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8906         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8907         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8908         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8909     };
8910
8911     /* Quad with R=0x10, G=0x20 */
8912     static const struct vertex quad1[] = {
8913         {-1.0f, -1.0f, 0.1f, 0x80102000},
8914         {-1.0f,  1.0f, 0.1f, 0x80102000},
8915         { 1.0f, -1.0f, 0.1f, 0x80102000},
8916         { 1.0f,  1.0f, 0.1f, 0x80102000},
8917     };
8918
8919     /* Quad with R=0x20, G=0x10 */
8920     static const struct vertex quad2[] = {
8921         {-1.0f, -1.0f, 0.1f, 0x80201000},
8922         {-1.0f,  1.0f, 0.1f, 0x80201000},
8923         { 1.0f, -1.0f, 0.1f, 0x80201000},
8924         { 1.0f,  1.0f, 0.1f, 0x80201000},
8925     };
8926
8927     IDirect3DDevice9_GetDirect3D(device, &d3d);
8928
8929     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8930     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8931     if(!backbuffer) {
8932         goto out;
8933     }
8934
8935     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8936     {
8937         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8938         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8939            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8940            continue;
8941         }
8942
8943         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8944         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8945
8946         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8947         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8948         if(!offscreenTexture) {
8949             continue;
8950         }
8951
8952         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8953         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8954         if(!offscreen) {
8955             continue;
8956         }
8957
8958         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8959         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8960
8961         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8962         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8963         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8964         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8965         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8966         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8967         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8968         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8970         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8971
8972         /* Below we will draw two quads with different colors and try to blend them together.
8973          * The result color is compared with the expected outcome.
8974          */
8975         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8976             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8977             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8978             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8979             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8980
8981             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8982             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8983
8984             /* Draw a quad using color 0x0010200 */
8985             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8986             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8987             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8988             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8989             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8990             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8991
8992             /* Draw a quad using color 0x0020100 */
8993             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8994             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8995             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8996             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8997             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8998             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8999
9000             /* We don't want to blend the result on the backbuffer */
9001             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9002             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9003
9004             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9005             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9006             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9007             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9008             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9009
9010             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9011             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9012
9013             /* This time with the texture */
9014             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9015             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9016
9017             IDirect3DDevice9_EndScene(device);
9018         }
9019         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9020
9021
9022         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9023             /* Compare the color of the center quad with our expectation */
9024             color = getPixelColor(device, 320, 240);
9025             r0 = (color & 0x00ff0000) >> 16;
9026             g0 = (color & 0x0000ff00) >>  8;
9027             b0 = (color & 0x000000ff) >>  0;
9028
9029             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9030             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9031             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9032
9033             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9034                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9035                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9036                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9037         } else {
9038             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9039              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9040              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9041             color = getPixelColor(device, 320, 240);
9042             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);
9043         }
9044
9045         IDirect3DDevice9_SetTexture(device, 0, NULL);
9046         if(offscreenTexture) {
9047             IDirect3DTexture9_Release(offscreenTexture);
9048         }
9049         if(offscreen) {
9050             IDirect3DSurface9_Release(offscreen);
9051         }
9052     }
9053
9054 out:
9055     /* restore things */
9056     if(backbuffer) {
9057         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9058         IDirect3DSurface9_Release(backbuffer);
9059     }
9060 }
9061
9062 static void tssargtemp_test(IDirect3DDevice9 *device)
9063 {
9064     HRESULT hr;
9065     DWORD color;
9066     static const struct vertex quad[] = {
9067         {-1.0,     -1.0,    0.1,    0x00ff0000},
9068         { 1.0,     -1.0,    0.1,    0x00ff0000},
9069         {-1.0,      1.0,    0.1,    0x00ff0000},
9070         { 1.0,      1.0,    0.1,    0x00ff0000}
9071     };
9072     D3DCAPS9 caps;
9073
9074     memset(&caps, 0, sizeof(caps));
9075     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9076     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9077     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9078         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9079         return;
9080     }
9081
9082     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9083     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9084
9085     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9086     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9087     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9088     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9089
9090     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9091     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9092     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9093     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9094     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9095     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9096
9097     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9098     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9099     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9100     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9101     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9102     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9103
9104     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9105     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9106
9107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9108     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9109     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9110     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9111
9112     hr = IDirect3DDevice9_BeginScene(device);
9113     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9114     if(SUCCEEDED(hr)) {
9115
9116         hr = IDirect3DDevice9_EndScene(device);
9117         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9118         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9119         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9120     }
9121     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9122     color = getPixelColor(device, 320, 240);
9123     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9124
9125     /* Set stage 1 back to default */
9126     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9127     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9128     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9129     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9130     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9131     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9132     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9133     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9134     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9135     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9136 }
9137
9138 struct testdata
9139 {
9140     DWORD idxVertex; /* number of instances in the first stream */
9141     DWORD idxColor; /* number of instances in the second stream */
9142     DWORD idxInstance; /* should be 1 ?? */
9143     DWORD color1; /* color 1 instance */
9144     DWORD color2; /* color 2 instance */
9145     DWORD color3; /* color 3 instance */
9146     DWORD color4; /* color 4 instance */
9147     WORD strVertex; /* specify which stream to use 0-2*/
9148     WORD strColor;
9149     WORD strInstance;
9150 };
9151
9152 static const struct testdata testcases[]=
9153 {
9154     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9155     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9156     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9157     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9158     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9159     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9160     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9161     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9162     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9163     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9164     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9165     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9166     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9167     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9168     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9169 /*
9170     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9171     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9172 */
9173 };
9174
9175 /* Drawing Indexed Geometry with instances*/
9176 static void stream_test(IDirect3DDevice9 *device)
9177 {
9178     IDirect3DVertexBuffer9 *vb = NULL;
9179     IDirect3DVertexBuffer9 *vb2 = NULL;
9180     IDirect3DVertexBuffer9 *vb3 = NULL;
9181     IDirect3DIndexBuffer9 *ib = NULL;
9182     IDirect3DVertexDeclaration9 *pDecl = NULL;
9183     IDirect3DVertexShader9 *shader = NULL;
9184     HRESULT hr;
9185     BYTE *data;
9186     DWORD color;
9187     DWORD ind;
9188     unsigned i;
9189
9190     const DWORD shader_code[] =
9191     {
9192         0xfffe0101,                                     /* vs_1_1 */
9193         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9194         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9195         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9196         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9197         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9198         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9199         0x0000ffff
9200     };
9201
9202     const float quad[][3] =
9203     {
9204         {-0.5f, -0.5f,  1.1f}, /*0 */
9205         {-0.5f,  0.5f,  1.1f}, /*1 */
9206         { 0.5f, -0.5f,  1.1f}, /*2 */
9207         { 0.5f,  0.5f,  1.1f}, /*3 */
9208     };
9209
9210     const float vertcolor[][4] =
9211     {
9212         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9213         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9214         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9215         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9216     };
9217
9218     /* 4 position for 4 instances */
9219     const float instancepos[][3] =
9220     {
9221         {-0.6f,-0.6f, 0.0f},
9222         { 0.6f,-0.6f, 0.0f},
9223         { 0.6f, 0.6f, 0.0f},
9224         {-0.6f, 0.6f, 0.0f},
9225     };
9226
9227     short indices[] = {0, 1, 2, 1, 2, 3};
9228
9229     D3DVERTEXELEMENT9 decl[] =
9230     {
9231         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9232         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9233         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9234         D3DDECL_END()
9235     };
9236
9237     /* set the default value because it isn't done in wine? */
9238     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9239     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9240
9241     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9242     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9243     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9244
9245     /* check wrong cases */
9246     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9247     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9248     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9249     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9250     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9251     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9252     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9253     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9254     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9255     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9256     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9257     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9258     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9259     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9260     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9261     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9262     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9263     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9264     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9265     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9266
9267     /* set the default value back */
9268     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9269     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9270
9271     /* create all VertexBuffers*/
9272     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9273     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9274     if(!vb) {
9275         skip("Failed to create a vertex buffer\n");
9276         return;
9277     }
9278     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9279     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9280     if(!vb2) {
9281         skip("Failed to create a vertex buffer\n");
9282         goto out;
9283     }
9284     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9285     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9286     if(!vb3) {
9287         skip("Failed to create a vertex buffer\n");
9288         goto out;
9289     }
9290
9291     /* create IndexBuffer*/
9292     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9293     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9294     if(!ib) {
9295         skip("Failed to create a index buffer\n");
9296         goto out;
9297     }
9298
9299     /* copy all Buffers (Vertex + Index)*/
9300     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9301     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9302     memcpy(data, quad, sizeof(quad));
9303     hr = IDirect3DVertexBuffer9_Unlock(vb);
9304     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9305     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9306     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9307     memcpy(data, vertcolor, sizeof(vertcolor));
9308     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9309     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9310     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9311     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9312     memcpy(data, instancepos, sizeof(instancepos));
9313     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9314     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9315     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9316     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9317     memcpy(data, indices, sizeof(indices));
9318     hr = IDirect3DIndexBuffer9_Unlock(ib);
9319     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9320
9321     /* create VertexShader */
9322     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9323     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9324     if(!shader) {
9325         skip("Failed to create a vetex shader\n");
9326         goto out;
9327     }
9328
9329     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9330     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9331
9332     hr = IDirect3DDevice9_SetIndices(device, ib);
9333     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9334
9335     /* run all tests */
9336     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9337     {
9338         struct testdata act = testcases[i];
9339         decl[0].Stream = act.strVertex;
9340         decl[1].Stream = act.strColor;
9341         decl[2].Stream = act.strInstance;
9342         /* create VertexDeclarations */
9343         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9344         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9345
9346         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9347         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9348
9349         hr = IDirect3DDevice9_BeginScene(device);
9350         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9351         if(SUCCEEDED(hr))
9352         {
9353             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9354             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9355
9356             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9357             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9358             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9359             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9360
9361             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9362             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9363             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9364             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9365
9366             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9367             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9368             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9369             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9370
9371             /* don't know if this is right (1*3 and 4*1)*/
9372             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9373             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9374             hr = IDirect3DDevice9_EndScene(device);
9375             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9376
9377             /* set all StreamSource && StreamSourceFreq back to default */
9378             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9379             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9380             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9381             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9382             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9383             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9384             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9385             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9386             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9387             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9388             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9389             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9390         }
9391
9392         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9393         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9394
9395         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9396         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9397
9398         color = getPixelColor(device, 160, 360);
9399         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9400         color = getPixelColor(device, 480, 360);
9401         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9402         color = getPixelColor(device, 480, 120);
9403         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9404         color = getPixelColor(device, 160, 120);
9405         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9406     }
9407
9408     hr = IDirect3DDevice9_SetIndices(device, NULL);
9409     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9410
9411 out:
9412     if(vb) IDirect3DVertexBuffer9_Release(vb);
9413     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9414     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9415     if(ib)IDirect3DIndexBuffer9_Release(ib);
9416     if(shader)IDirect3DVertexShader9_Release(shader);
9417 }
9418
9419 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9420     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9421     IDirect3DTexture9 *dsttex = NULL;
9422     HRESULT hr;
9423     DWORD color;
9424     D3DRECT r1 = {0,  0,  50,  50 };
9425     D3DRECT r2 = {50, 0,  100, 50 };
9426     D3DRECT r3 = {50, 50, 100, 100};
9427     D3DRECT r4 = {0,  50,  50, 100};
9428     const float quad[] = {
9429         -1.0,   -1.0,   0.1,    0.0,    0.0,
9430          1.0,   -1.0,   0.1,    1.0,    0.0,
9431         -1.0,    1.0,   0.1,    0.0,    1.0,
9432          1.0,    1.0,   0.1,    1.0,    1.0,
9433     };
9434
9435     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9436     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9437
9438     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9439     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9440     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9441     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9442
9443     if(!src || !dsttex) {
9444         skip("One or more test resources could not be created\n");
9445         goto cleanup;
9446     }
9447
9448     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9449     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9450
9451     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9452     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9453
9454     /* Clear the StretchRect destination for debugging */
9455     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9456     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9457     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9458     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9459
9460     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9461     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9462
9463     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9464     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9465     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9466     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9467     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9468     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9469     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9470     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9471
9472     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9473      * the target -> texture GL blit path
9474      */
9475     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9476     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9477     IDirect3DSurface9_Release(dst);
9478
9479     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9480     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9481
9482     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9483     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9484     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9485     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9486     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9487     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9488     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9489     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9490
9491     hr = IDirect3DDevice9_BeginScene(device);
9492     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9493     if(SUCCEEDED(hr)) {
9494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9495         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9496         hr = IDirect3DDevice9_EndScene(device);
9497         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9498     }
9499
9500     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9501     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9502     color = getPixelColor(device, 160, 360);
9503     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9504     color = getPixelColor(device, 480, 360);
9505     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9506     color = getPixelColor(device, 480, 120);
9507     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9508     color = getPixelColor(device, 160, 120);
9509     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9510
9511     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9512     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9513     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9514     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9515
9516 cleanup:
9517     if(src) IDirect3DSurface9_Release(src);
9518     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9519     if(dsttex) IDirect3DTexture9_Release(dsttex);
9520 }
9521
9522 static void texop_test(IDirect3DDevice9 *device)
9523 {
9524     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9525     IDirect3DTexture9 *texture = NULL;
9526     D3DLOCKED_RECT locked_rect;
9527     D3DCOLOR color;
9528     D3DCAPS9 caps;
9529     HRESULT hr;
9530     unsigned i;
9531
9532     static const struct {
9533         float x, y, z;
9534         float s, t;
9535         D3DCOLOR diffuse;
9536     } quad[] = {
9537         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9538         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9539         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9540         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9541     };
9542
9543     static const D3DVERTEXELEMENT9 decl_elements[] = {
9544         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9545         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9546         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9547         D3DDECL_END()
9548     };
9549
9550     static const struct {
9551         D3DTEXTUREOP op;
9552         const char *name;
9553         DWORD caps_flag;
9554         D3DCOLOR result;
9555     } test_data[] = {
9556         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9557         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9558         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9559         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9560         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9561         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9562         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9563         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9564         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9565         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9566         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9567         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9568         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9569         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9570         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9571         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9572         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9573         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9574         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9575         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9576         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9577         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9578         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9579     };
9580
9581     memset(&caps, 0, sizeof(caps));
9582     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9583     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9584
9585     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9586     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9587     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9588     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9589
9590     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9591     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9592     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9593     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9594     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9595     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9596     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9597     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9598     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9599
9600     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9601     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9602     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9603     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9604     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9605     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9606
9607     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9608     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9609
9610     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9611     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9612     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9613     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9614     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9615     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9616
9617     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9618     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9619
9620     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9621     {
9622         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9623         {
9624             skip("tex operation %s not supported\n", test_data[i].name);
9625             continue;
9626         }
9627
9628         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9629         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9630
9631         hr = IDirect3DDevice9_BeginScene(device);
9632         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9633
9634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9635         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9636
9637         hr = IDirect3DDevice9_EndScene(device);
9638         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9639
9640         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9641         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9642
9643         color = getPixelColor(device, 320, 240);
9644         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9645                 test_data[i].name, color, test_data[i].result);
9646     }
9647
9648     if (texture) IDirect3DTexture9_Release(texture);
9649     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9650 }
9651
9652 static void yuv_color_test(IDirect3DDevice9 *device) {
9653     HRESULT hr;
9654     IDirect3DSurface9 *surface = NULL, *target = NULL;
9655     unsigned int fmt, i;
9656     D3DFORMAT format;
9657     const char *fmt_string;
9658     D3DLOCKED_RECT lr;
9659     IDirect3D9 *d3d;
9660     HRESULT color;
9661     DWORD ref_color_left, ref_color_right;
9662
9663     struct {
9664         DWORD in;           /* The input color */
9665         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9666         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9667         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9668         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9669     } test_data[] = {
9670     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9671      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9672      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9673      * that
9674      */
9675       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9676       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9677       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9678       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9679       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9680       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9681       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9682       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9683       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9684       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9685       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9686       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9687       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9688       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9689
9690       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9691       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9692       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9693       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9694     };
9695
9696     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9697     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9698     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9699     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9700
9701     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9702     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9703
9704     for(fmt = 0; fmt < 2; fmt++) {
9705         if(fmt == 0) {
9706             format = D3DFMT_UYVY;
9707             fmt_string = "D3DFMT_UYVY";
9708         } else {
9709             format = D3DFMT_YUY2;
9710             fmt_string = "D3DFMT_YUY2";
9711         }
9712
9713         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9714                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9715                        */
9716         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9717                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9718             skip("%s is not supported\n", fmt_string);
9719             continue;
9720         }
9721
9722         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9723         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9724         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9725
9726         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9727             if(fmt == 0) {
9728                 ref_color_left = test_data[i].uyvy_left;
9729                 ref_color_right = test_data[i].uyvy_right;
9730             } else {
9731                 ref_color_left = test_data[i].yuy2_left;
9732                 ref_color_right = test_data[i].yuy2_right;
9733             }
9734
9735             memset(&lr, 0, sizeof(lr));
9736             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9737             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9738             *((DWORD *) lr.pBits) = test_data[i].in;
9739             hr = IDirect3DSurface9_UnlockRect(surface);
9740             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9741
9742             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9743             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9744             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9745             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9746             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9747             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9748
9749             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9750              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9751              * want to add tests for the filtered pixels as well.
9752              *
9753              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9754              * differently, so we need a max diff of 16
9755              */
9756             color = getPixelColor(device, 40, 240);
9757             ok(color_match(color, ref_color_left, 16),
9758                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9759                test_data[i].in, color, ref_color_left, fmt_string);
9760             color = getPixelColor(device, 600, 240);
9761             ok(color_match(color, ref_color_right, 16),
9762                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9763                test_data[i].in, color, ref_color_right, fmt_string);
9764         }
9765         IDirect3DSurface9_Release(surface);
9766     }
9767     IDirect3DSurface9_Release(target);
9768     IDirect3D9_Release(d3d);
9769 }
9770
9771 static void texop_range_test(IDirect3DDevice9 *device)
9772 {
9773     static const struct {
9774         float x, y, z;
9775         D3DCOLOR diffuse;
9776     } quad[] = {
9777         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9778         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9779         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9780         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9781     };
9782     HRESULT hr;
9783     IDirect3DTexture9 *texture;
9784     D3DLOCKED_RECT locked_rect;
9785     D3DCAPS9 caps;
9786     DWORD color;
9787
9788     /* We need ADD and SUBTRACT operations */
9789     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9790     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9791     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9792         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9793         return;
9794     }
9795     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9796         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9797         return;
9798     }
9799
9800     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9801     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9802     /* Stage 1: result = diffuse(=1.0) + diffuse
9803      * stage 2: result = result - tfactor(= 0.5)
9804      */
9805     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9806     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9807     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9808     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9809     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9810     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9811     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9812     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9813     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9814     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9815     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9816     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9817     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9818     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9819
9820     hr = IDirect3DDevice9_BeginScene(device);
9821     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9822     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9823     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9824     hr = IDirect3DDevice9_EndScene(device);
9825     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9826     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9827     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9828
9829     color = getPixelColor(device, 320, 240);
9830     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9831        color);
9832
9833     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9834     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9835     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9836     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9837     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9838     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9839     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9840     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9841     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9842
9843     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9844      * stage 2: result = result + diffuse(1.0)
9845      */
9846     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9847     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9848     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9849     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9850     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9851     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9852     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9853     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9854     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9855     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9856     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9857     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9858     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9859     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9860
9861     hr = IDirect3DDevice9_BeginScene(device);
9862     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9863     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9864     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9865     hr = IDirect3DDevice9_EndScene(device);
9866     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9867     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9868     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9869
9870     color = getPixelColor(device, 320, 240);
9871     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9872        color);
9873
9874     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9875     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9876     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9877     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9878     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9879     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9880     IDirect3DTexture9_Release(texture);
9881 }
9882
9883 static void alphareplicate_test(IDirect3DDevice9 *device) {
9884     struct vertex quad[] = {
9885         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9886         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9887         { -1.0,     1.0,    0.1,    0x80ff00ff },
9888         {  1.0,     1.0,    0.1,    0x80ff00ff },
9889     };
9890     HRESULT hr;
9891     DWORD color;
9892
9893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9894     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9895
9896     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9897     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9898
9899     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9900     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9901     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9902     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9903
9904     hr = IDirect3DDevice9_BeginScene(device);
9905     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9906     if(SUCCEEDED(hr)) {
9907         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9908         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9909         hr = IDirect3DDevice9_EndScene(device);
9910         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9911     }
9912
9913     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9914     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9915
9916     color = getPixelColor(device, 320, 240);
9917     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9918        color);
9919
9920     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9921     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9922
9923 }
9924
9925 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9926     HRESULT hr;
9927     D3DCAPS9 caps;
9928     DWORD color;
9929     struct vertex quad[] = {
9930         { -1.0,    -1.0,    0.1,    0x408080c0 },
9931         {  1.0,    -1.0,    0.1,    0x408080c0 },
9932         { -1.0,     1.0,    0.1,    0x408080c0 },
9933         {  1.0,     1.0,    0.1,    0x408080c0 },
9934     };
9935
9936     memset(&caps, 0, sizeof(caps));
9937     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9938     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9939     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9940         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9941         return;
9942     }
9943
9944     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9945     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9946
9947     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9948     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9949
9950     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9951      * mov r0.a, diffuse.a
9952      * mov r0, r0.a
9953      *
9954      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9955      * 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
9956      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9957      */
9958     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9959     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9961     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9962     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9963     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9964     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9965     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9966     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9967     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9968     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9969     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9970     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9971     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9972     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9973     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9974     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9975     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9976
9977     hr = IDirect3DDevice9_BeginScene(device);
9978     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9979     if(SUCCEEDED(hr)) {
9980         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9981         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9982         hr = IDirect3DDevice9_EndScene(device);
9983         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9984     }
9985
9986     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9987     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9988
9989     color = getPixelColor(device, 320, 240);
9990     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9991        color);
9992
9993     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9994     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9995     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9996     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9997     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9998     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9999 }
10000
10001 static void zwriteenable_test(IDirect3DDevice9 *device) {
10002     HRESULT hr;
10003     DWORD color;
10004     struct vertex quad1[] = {
10005         { -1.0,  -1.0,  0.1,    0x00ff0000},
10006         { -1.0,   1.0,  0.1,    0x00ff0000},
10007         {  1.0,  -1.0,  0.1,    0x00ff0000},
10008         {  1.0,   1.0,  0.1,    0x00ff0000},
10009     };
10010     struct vertex quad2[] = {
10011         { -1.0,  -1.0,  0.9,    0x0000ff00},
10012         { -1.0,   1.0,  0.9,    0x0000ff00},
10013         {  1.0,  -1.0,  0.9,    0x0000ff00},
10014         {  1.0,   1.0,  0.9,    0x0000ff00},
10015     };
10016
10017     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10018     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10019
10020     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10021     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10022     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10023     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10024     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10025     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10026     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10027     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10028
10029     hr = IDirect3DDevice9_BeginScene(device);
10030     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10031     if(SUCCEEDED(hr)) {
10032         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10033          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10034          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10035          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10036          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10037          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10038          */
10039         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10040         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10041         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10042         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10043         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10044         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10045
10046         hr = IDirect3DDevice9_EndScene(device);
10047         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10048     }
10049
10050     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10051     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10052     color = getPixelColor(device, 320, 240);
10053     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10054        color);
10055
10056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10058 }
10059
10060 static void alphatest_test(IDirect3DDevice9 *device) {
10061 #define ALPHATEST_PASSED 0x0000ff00
10062 #define ALPHATEST_FAILED 0x00ff0000
10063     struct {
10064         D3DCMPFUNC  func;
10065         DWORD       color_less;
10066         DWORD       color_equal;
10067         DWORD       color_greater;
10068     } testdata[] = {
10069         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10070         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10071         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10072         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10073         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10074         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10075         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10076         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10077     };
10078     unsigned int i, j;
10079     HRESULT hr;
10080     DWORD color;
10081     struct vertex quad[] = {
10082         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10083         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10084         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10085         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10086     };
10087     D3DCAPS9 caps;
10088
10089     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10090     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10091     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10092     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10093
10094     for(j = 0; j < 2; j++) {
10095         if(j == 1) {
10096             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10097              * the alpha test either for performance reasons(floating point RTs) or to work
10098              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10099              * codepath for ffp and shader in this case, and the test should cover both
10100              */
10101             IDirect3DPixelShader9 *ps;
10102             DWORD shader_code[] = {
10103                 0xffff0101,                                 /* ps_1_1           */
10104                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10105                 0x0000ffff                                  /* end              */
10106             };
10107             memset(&caps, 0, sizeof(caps));
10108             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10109             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10110             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10111                 break;
10112             }
10113
10114             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10115             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10116             IDirect3DDevice9_SetPixelShader(device, ps);
10117             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10118             IDirect3DPixelShader9_Release(ps);
10119         }
10120
10121         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10122             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10123             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10124
10125             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10126             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10127             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10128             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10129             hr = IDirect3DDevice9_BeginScene(device);
10130             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10131             if(SUCCEEDED(hr)) {
10132                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10133                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10134                 hr = IDirect3DDevice9_EndScene(device);
10135                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10136             }
10137             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10138             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10139             color = getPixelColor(device, 320, 240);
10140             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10141             color, testdata[i].color_less, testdata[i].func);
10142
10143             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10144             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10145             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10146             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10147             hr = IDirect3DDevice9_BeginScene(device);
10148             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10149             if(SUCCEEDED(hr)) {
10150                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10151                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10152                 hr = IDirect3DDevice9_EndScene(device);
10153                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10154             }
10155             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10156             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10157             color = getPixelColor(device, 320, 240);
10158             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10159             color, testdata[i].color_equal, testdata[i].func);
10160
10161             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10162             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10163             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10164             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10165             hr = IDirect3DDevice9_BeginScene(device);
10166             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10167             if(SUCCEEDED(hr)) {
10168                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10169                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10170                 hr = IDirect3DDevice9_EndScene(device);
10171                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10172             }
10173             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10174             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10175             color = getPixelColor(device, 320, 240);
10176             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10177             color, testdata[i].color_greater, testdata[i].func);
10178         }
10179     }
10180
10181     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10182     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10183     IDirect3DDevice9_SetPixelShader(device, NULL);
10184     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10185 }
10186
10187 static void sincos_test(IDirect3DDevice9 *device) {
10188     const DWORD sin_shader_code[] = {
10189         0xfffe0200,                                                                 /* vs_2_0                       */
10190         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10191         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10192         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10193         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10194         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10195         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10196         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10197         0x0000ffff                                                                  /* end                          */
10198     };
10199     const DWORD cos_shader_code[] = {
10200         0xfffe0200,                                                                 /* vs_2_0                       */
10201         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10202         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10203         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10204         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10205         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10206         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10207         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10208         0x0000ffff                                                                  /* end                          */
10209     };
10210     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10211     HRESULT hr;
10212     struct {
10213         float x, y, z;
10214     } data[1280];
10215     unsigned int i;
10216     float sincosc1[4] = {D3DSINCOSCONST1};
10217     float sincosc2[4] = {D3DSINCOSCONST2};
10218
10219     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10220     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10221
10222     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10223     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10224     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10225     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10226     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10227     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10228     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10229     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10230     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10231     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10232
10233     /* Generate a point from -1 to 1 every 0.5 pixels */
10234     for(i = 0; i < 1280; i++) {
10235         data[i].x = (-640.0 + i) / 640.0;
10236         data[i].y = 0.0;
10237         data[i].z = 0.1;
10238     }
10239
10240     hr = IDirect3DDevice9_BeginScene(device);
10241     if(SUCCEEDED(hr)) {
10242         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10243         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10244         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10245         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10246
10247         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10248         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10249         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10250         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10251
10252         hr = IDirect3DDevice9_EndScene(device);
10253         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10254     }
10255     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10256     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10257
10258     IDirect3DDevice9_SetVertexShader(device, NULL);
10259     IDirect3DVertexShader9_Release(sin_shader);
10260     IDirect3DVertexShader9_Release(cos_shader);
10261 }
10262
10263 static void loop_index_test(IDirect3DDevice9 *device) {
10264     const DWORD shader_code[] = {
10265         0xfffe0200,                                                 /* vs_2_0                   */
10266         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10267         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10268         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10269         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10270         0x0000001d,                                                 /* endloop                  */
10271         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10272         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10273         0x0000ffff                                                  /* END                      */
10274     };
10275     IDirect3DVertexShader9 *shader;
10276     HRESULT hr;
10277     DWORD color;
10278     const float quad[] = {
10279         -1.0,   -1.0,   0.1,
10280          1.0,   -1.0,   0.1,
10281         -1.0,    1.0,   0.1,
10282          1.0,    1.0,   0.1
10283     };
10284     const float zero[4] = {0, 0, 0, 0};
10285     const float one[4] = {1, 1, 1, 1};
10286     int i0[4] = {2, 10, -3, 0};
10287     float values[4];
10288
10289     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10290     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10291     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10292     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10293     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10294     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10295     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10296     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10297
10298     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10299     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10300     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10301     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10302     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10303     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10304     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10305     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10306     values[0] = 1.0;
10307     values[1] = 1.0;
10308     values[2] = 0.0;
10309     values[3] = 0.0;
10310     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10311     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10312     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10313     values[0] = -1.0;
10314     values[1] = 0.0;
10315     values[2] = 0.0;
10316     values[3] = 0.0;
10317     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10318     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10319     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10320     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10321     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10322
10323     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10324
10325     hr = IDirect3DDevice9_BeginScene(device);
10326     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10327     if(SUCCEEDED(hr))
10328     {
10329         trace("going to draw index\n");
10330         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10331         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10332         hr = IDirect3DDevice9_EndScene(device);
10333         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10334     }
10335     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10336     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10337
10338     color = getPixelColor(device, 320, 240);
10339     ok(color_match(color, 0x0000ff00, 1),
10340        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10341
10342     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10343     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10344     IDirect3DVertexShader9_Release(shader);
10345 }
10346
10347 static void sgn_test(IDirect3DDevice9 *device) {
10348     const DWORD shader_code[] = {
10349         0xfffe0200,                                                             /* vs_2_0                       */
10350         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10351         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10352         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10353         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10354         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10355         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10356         0x0000ffff                                                              /* end                          */
10357     };
10358     IDirect3DVertexShader9 *shader;
10359     HRESULT hr;
10360     DWORD color;
10361     const float quad[] = {
10362         -1.0,   -1.0,   0.1,
10363          1.0,   -1.0,   0.1,
10364         -1.0,    1.0,   0.1,
10365          1.0,    1.0,   0.1
10366     };
10367
10368     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10369     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10370     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10371     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10372     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10373     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10374     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10375     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10376
10377     hr = IDirect3DDevice9_BeginScene(device);
10378     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10379     if(SUCCEEDED(hr))
10380     {
10381         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10382         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10383         hr = IDirect3DDevice9_EndScene(device);
10384         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10385     }
10386     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10387     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10388
10389     color = getPixelColor(device, 320, 240);
10390     ok(color_match(color, 0x008000ff, 1),
10391        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10392
10393     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10394     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10395     IDirect3DVertexShader9_Release(shader);
10396 }
10397
10398 static void viewport_test(IDirect3DDevice9 *device) {
10399     HRESULT hr;
10400     DWORD color;
10401     D3DVIEWPORT9 vp, old_vp;
10402     const float quad[] =
10403     {
10404         -0.5,   -0.5,   0.1,
10405          0.5,   -0.5,   0.1,
10406         -0.5,    0.5,   0.1,
10407          0.5,    0.5,   0.1
10408     };
10409
10410     memset(&old_vp, 0, sizeof(old_vp));
10411     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10412     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10413
10414     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10415     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10416
10417     /* Test a viewport with Width and Height bigger than the surface dimensions
10418      *
10419      * TODO: Test Width < surface.width, but X + Width > surface.width
10420      * TODO: Test Width < surface.width, what happens with the height?
10421      */
10422     memset(&vp, 0, sizeof(vp));
10423     vp.X = 0;
10424     vp.Y = 0;
10425     vp.Width = 10000;
10426     vp.Height = 10000;
10427     vp.MinZ = 0.0;
10428     vp.MaxZ = 0.0;
10429     hr = IDirect3DDevice9_SetViewport(device, &vp);
10430     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10431
10432     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10433     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10434     hr = IDirect3DDevice9_BeginScene(device);
10435     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10436     if(SUCCEEDED(hr))
10437     {
10438         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10439         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10440         hr = IDirect3DDevice9_EndScene(device);
10441         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10442     }
10443     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10444
10445     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10446     color = getPixelColor(device, 158, 118);
10447     ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10448     color = getPixelColor(device, 162, 118);
10449     ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10450     color = getPixelColor(device, 158, 122);
10451     ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10452     color = getPixelColor(device, 162, 122);
10453     ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10454
10455     color = getPixelColor(device, 478, 358);
10456     ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10457     color = getPixelColor(device, 482, 358);
10458     ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10459     color = getPixelColor(device, 478, 362);
10460     ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10461     color = getPixelColor(device, 482, 362);
10462     ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10463
10464     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10465     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10466 }
10467
10468 START_TEST(visual)
10469 {
10470     IDirect3DDevice9 *device_ptr;
10471     D3DCAPS9 caps;
10472     HRESULT hr;
10473     DWORD color;
10474
10475     d3d9_handle = LoadLibraryA("d3d9.dll");
10476     if (!d3d9_handle)
10477     {
10478         skip("Could not load d3d9.dll\n");
10479         return;
10480     }
10481
10482     device_ptr = init_d3d9();
10483     if (!device_ptr)
10484     {
10485         skip("Creating the device failed\n");
10486         return;
10487     }
10488
10489     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10490
10491     /* Check for the reliability of the returned data */
10492     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10493     if(FAILED(hr))
10494     {
10495         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10496         goto cleanup;
10497     }
10498     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10499
10500     color = getPixelColor(device_ptr, 1, 1);
10501     if(color !=0x00ff0000)
10502     {
10503         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10504         goto cleanup;
10505     }
10506
10507     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10508     if(FAILED(hr))
10509     {
10510         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10511         goto cleanup;
10512     }
10513     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10514
10515     color = getPixelColor(device_ptr, 639, 479);
10516     if(color != 0x0000ddee)
10517     {
10518         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10519         goto cleanup;
10520     }
10521
10522     /* Now execute the real tests */
10523     stretchrect_test(device_ptr);
10524     lighting_test(device_ptr);
10525     clear_test(device_ptr);
10526     fog_test(device_ptr);
10527     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10528     {
10529         test_cube_wrap(device_ptr);
10530     } else {
10531         skip("No cube texture support\n");
10532     }
10533     z_range_test(device_ptr);
10534     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10535     {
10536         maxmip_test(device_ptr);
10537     }
10538     else
10539     {
10540         skip("No mipmap support\n");
10541     }
10542     offscreen_test(device_ptr);
10543     alpha_test(device_ptr);
10544     shademode_test(device_ptr);
10545     srgbtexture_test(device_ptr);
10546     release_buffer_test(device_ptr);
10547     float_texture_test(device_ptr);
10548     g16r16_texture_test(device_ptr);
10549     pixelshader_blending_test(device_ptr);
10550     texture_transform_flags_test(device_ptr);
10551     autogen_mipmap_test(device_ptr);
10552     fixed_function_decl_test(device_ptr);
10553     conditional_np2_repeat_test(device_ptr);
10554     fixed_function_bumpmap_test(device_ptr);
10555     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10556         stencil_cull_test(device_ptr);
10557     } else {
10558         skip("No two sided stencil support\n");
10559     }
10560     pointsize_test(device_ptr);
10561     tssargtemp_test(device_ptr);
10562     np2_stretch_rect_test(device_ptr);
10563     yuv_color_test(device_ptr);
10564     zwriteenable_test(device_ptr);
10565     alphatest_test(device_ptr);
10566     viewport_test(device_ptr);
10567
10568     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10569     {
10570         test_constant_clamp_vs(device_ptr);
10571         test_compare_instructions(device_ptr);
10572     }
10573     else skip("No vs_1_1 support\n");
10574
10575     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10576     {
10577         test_mova(device_ptr);
10578         loop_index_test(device_ptr);
10579         sincos_test(device_ptr);
10580         sgn_test(device_ptr);
10581         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10582             test_vshader_input(device_ptr);
10583             test_vshader_float16(device_ptr);
10584             stream_test(device_ptr);
10585         } else {
10586             skip("No vs_3_0 support\n");
10587         }
10588     }
10589     else skip("No vs_2_0 support\n");
10590
10591     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10592     {
10593         fog_with_shader_test(device_ptr);
10594         fog_srgbwrite_test(device_ptr);
10595     }
10596     else skip("No vs_1_1 and ps_1_1 support\n");
10597
10598     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10599     {
10600         texbem_test(device_ptr);
10601         texdepth_test(device_ptr);
10602         texkill_test(device_ptr);
10603         x8l8v8u8_test(device_ptr);
10604         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10605             constant_clamp_ps_test(device_ptr);
10606             cnd_test(device_ptr);
10607             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10608                 dp2add_ps_test(device_ptr);
10609                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10610                     nested_loop_test(device_ptr);
10611                     fixed_function_varying_test(device_ptr);
10612                     vFace_register_test(device_ptr);
10613                     vpos_register_test(device_ptr);
10614                     multiple_rendertargets_test(device_ptr);
10615                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10616                         vshader_version_varying_test(device_ptr);
10617                         pshader_version_varying_test(device_ptr);
10618                     } else {
10619                         skip("No vs_3_0 support\n");
10620                     }
10621                 } else {
10622                     skip("No ps_3_0 support\n");
10623                 }
10624             } else {
10625                 skip("No ps_2_0 support\n");
10626             }
10627         }
10628     }
10629     else skip("No ps_1_1 support\n");
10630
10631     texop_test(device_ptr);
10632     texop_range_test(device_ptr);
10633     alphareplicate_test(device_ptr);
10634     dp3_alpha_test(device_ptr);
10635
10636 cleanup:
10637     if(device_ptr) {
10638         D3DPRESENT_PARAMETERS present_parameters;
10639         IDirect3DSwapChain9 *swapchain;
10640         ULONG ref;
10641
10642         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10643         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10644         DestroyWindow(present_parameters.hDeviceWindow);
10645         IDirect3DSwapChain9_Release(swapchain);
10646         ref = IDirect3DDevice9_Release(device_ptr);
10647         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10648     }
10649 }