d3d9/tests: Add a test for clearing render targets in an MRT.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 Henri Verbeet
3  * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 static HWND create_window(void)
38 {
39     WNDCLASS wc = {0};
40     HWND ret;
41     wc.lpfnWndProc = DefWindowProc;
42     wc.lpszClassName = "d3d9_test_wc";
43     RegisterClass(&wc);
44
45     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47     ShowWindow(ret, SW_SHOW);
48     return ret;
49 }
50
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 {
53     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54     c1 >>= 8; c2 >>= 8;
55     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56     c1 >>= 8; c2 >>= 8;
57     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58     c1 >>= 8; c2 >>= 8;
59     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60     return TRUE;
61 }
62
63 /* Locks a given surface and returns the color at (x,y).  It's the caller's
64  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 {
67     DWORD color;
68     HRESULT hr;
69     D3DSURFACE_DESC desc;
70     RECT rectToLock = {x, y, x+1, y+1};
71     D3DLOCKED_RECT lockedRect;
72
73     hr = IDirect3DSurface9_GetDesc(surface, &desc);
74     if(FAILED(hr))  /* This is not a test */
75     {
76         trace("Can't get the surface description, hr=%08x\n", hr);
77         return 0xdeadbeef;
78     }
79
80     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81     if(FAILED(hr))  /* This is not a test */
82     {
83         trace("Can't lock the surface, hr=%08x\n", hr);
84         return 0xdeadbeef;
85     }
86     switch(desc.Format) {
87         case D3DFMT_A8R8G8B8:
88         {
89             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90             break;
91         }
92         default:
93             trace("Error: unknown surface format: %d\n", desc.Format);
94             color = 0xdeadbeef;
95             break;
96     }
97     hr = IDirect3DSurface9_UnlockRect(surface);
98     if(FAILED(hr))
99     {
100         trace("Can't unlock the surface, hr=%08x\n", hr);
101     }
102     return color;
103 }
104
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 {
107     DWORD ret;
108     IDirect3DSurface9 *surf = NULL, *target = NULL;
109     HRESULT hr;
110     D3DLOCKED_RECT lockedRect;
111     RECT rectToLock = {x, y, x+1, y+1};
112
113     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114     if(FAILED(hr) || !surf )  /* This is not a test */
115     {
116         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117         return 0xdeadbeef;
118     }
119
120     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121     if(FAILED(hr))
122     {
123         trace("Can't get the render target, hr=%08x\n", hr);
124         ret = 0xdeadbeed;
125         goto out;
126     }
127
128     hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129     if(FAILED(hr))
130     {
131         trace("Can't read the render target data, hr=%08x\n", hr);
132         ret = 0xdeadbeec;
133         goto out;
134     }
135
136     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137     if(FAILED(hr))
138     {
139         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140         ret = 0xdeadbeeb;
141         goto out;
142     }
143
144     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145      * really important for these tests
146      */
147     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148     hr = IDirect3DSurface9_UnlockRect(surf);
149     if(FAILED(hr))
150     {
151         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
152     }
153
154 out:
155     if(target) IDirect3DSurface9_Release(target);
156     if(surf) IDirect3DSurface9_Release(surf);
157     return ret;
158 }
159
160 static IDirect3DDevice9 *init_d3d9(void)
161 {
162     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163     IDirect3D9 *d3d9_ptr = 0;
164     IDirect3DDevice9 *device_ptr = 0;
165     D3DPRESENT_PARAMETERS present_parameters;
166     HRESULT hr;
167     D3DADAPTER_IDENTIFIER9 identifier;
168
169     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171     if (!d3d9_create) return NULL;
172
173     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174     if (!d3d9_ptr)
175     {
176         skip("could not create D3D9\n");
177         return NULL;
178     }
179
180     ZeroMemory(&present_parameters, sizeof(present_parameters));
181     present_parameters.Windowed = TRUE;
182     present_parameters.hDeviceWindow = create_window();
183     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184     present_parameters.BackBufferWidth = 640;
185     present_parameters.BackBufferHeight = 480;
186     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187     present_parameters.EnableAutoDepthStencil = TRUE;
188     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
189
190     memset(&identifier, 0, sizeof(identifier));
191     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193     trace("Driver string: \"%s\"\n", identifier.Driver);
194     trace("Description string: \"%s\"\n", identifier.Description);
195     ok(identifier.Description[0] != '\0', "Empty driver description\n");
196     trace("Device name string: \"%s\"\n", identifier.DeviceName);
197     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
198     trace("Driver version %d.%d.%d.%d\n",
199           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
201
202     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203     if(FAILED(hr)) {
204         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206         if(FAILED(hr)) {
207             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
208         }
209     }
210     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
211
212     return device_ptr;
213 }
214
215 struct vertex
216 {
217     float x, y, z;
218     DWORD diffuse;
219 };
220
221 struct tvertex
222 {
223     float x, y, z, rhw;
224     DWORD diffuse;
225 };
226
227 struct nvertex
228 {
229     float x, y, z;
230     float nx, ny, nz;
231     DWORD diffuse;
232 };
233
234 static void lighting_test(IDirect3DDevice9 *device)
235 {
236     HRESULT hr;
237     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239     DWORD color;
240     D3DMATERIAL9 material, old_material;
241     DWORD cop, carg;
242
243     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244                       0.0f, 1.0f, 0.0f, 0.0f,
245                       0.0f, 0.0f, 1.0f, 0.0f,
246                       0.0f, 0.0f, 0.0f, 1.0f };
247
248     struct vertex unlitquad[] =
249     {
250         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
251         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
252         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
253         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
254     };
255     struct vertex litquad[] =
256     {
257         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
258         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
259         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
260         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
261     };
262     struct nvertex unlitnquad[] =
263     {
264         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
266         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
267         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
268     };
269     struct nvertex litnquad[] =
270     {
271         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
273         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
274         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
275     };
276     WORD Indices[] = {0, 1, 2, 2, 3, 0};
277
278     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
280
281     /* Setup some states that may cause issues */
282     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
306
307     hr = IDirect3DDevice9_SetFVF(device, 0);
308     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309
310     hr = IDirect3DDevice9_SetFVF(device, fvf);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
312
313     hr = IDirect3DDevice9_BeginScene(device);
314     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315     if(hr == D3D_OK)
316     {
317         /* No lights are defined... That means, lit vertices should be entirely black */
318         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323
324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329
330         hr = IDirect3DDevice9_SetFVF(device, nfvf);
331         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
332
333         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
338
339         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
344
345         IDirect3DDevice9_EndScene(device);
346         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
347     }
348
349     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
357
358     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359
360     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362     memset(&material, 0, sizeof(material));
363     material.Diffuse.r = 0.0;
364     material.Diffuse.g = 0.0;
365     material.Diffuse.b = 0.0;
366     material.Diffuse.a = 1.0;
367     material.Ambient.r = 0.0;
368     material.Ambient.g = 0.0;
369     material.Ambient.b = 0.0;
370     material.Ambient.a = 0.0;
371     material.Specular.r = 0.0;
372     material.Specular.g = 0.0;
373     material.Specular.b = 0.0;
374     material.Specular.a = 0.0;
375     material.Emissive.r = 0.0;
376     material.Emissive.g = 0.0;
377     material.Emissive.b = 0.0;
378     material.Emissive.a = 0.0;
379     material.Power = 0.0;
380     IDirect3DDevice9_SetMaterial(device, &material);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382
383     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387
388     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396
397     hr = IDirect3DDevice9_BeginScene(device);
398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399     if(SUCCEEDED(hr)) {
400         struct vertex lighting_test[] = {
401             {-1.0,   -1.0,   0.1,    0x8000ff00},
402             { 1.0,   -1.0,   0.1,    0x80000000},
403             {-1.0,    1.0,   0.1,    0x8000ff00},
404             { 1.0,    1.0,   0.1,    0x80000000}
405         };
406         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410
411         hr = IDirect3DDevice9_EndScene(device);
412         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
413     }
414
415     color = getPixelColor(device, 320, 240);
416     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418
419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
431 }
432
433 static void clear_test(IDirect3DDevice9 *device)
434 {
435     /* Tests the correctness of clearing parameters */
436     HRESULT hr;
437     D3DRECT rect[2];
438     D3DRECT rect_negneg;
439     DWORD color;
440     D3DVIEWPORT9 old_vp, vp;
441     RECT scissor;
442     DWORD oldColorWrite;
443     BOOL invalid_clear_failed = FALSE;
444
445     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
447
448     /* Positive x, negative y */
449     rect[0].x1 = 0;
450     rect[0].y1 = 480;
451     rect[0].x2 = 320;
452     rect[0].y2 = 240;
453
454     /* Positive x, positive y */
455     rect[1].x1 = 0;
456     rect[1].y1 = 0;
457     rect[1].x2 = 320;
458     rect[1].y2 = 240;
459     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460      * returns D3D_OK, but ignores the rectangle silently
461      */
462     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465
466     /* negative x, negative y */
467     rect_negneg.x1 = 640;
468     rect_negneg.y1 = 240;
469     rect_negneg.x2 = 320;
470     rect_negneg.y2 = 0;
471     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
474
475     color = getPixelColor(device, 160, 360); /* lower left quad */
476     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477     color = getPixelColor(device, 160, 120); /* upper left quad */
478     if(invalid_clear_failed) {
479         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481     } else {
482         /* If the negative rectangle was dropped silently, the correct ones are cleared */
483         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
484     }
485     color = getPixelColor(device, 480, 360); /* lower right quad  */
486     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487     color = getPixelColor(device, 480, 120); /* upper right quad */
488     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
489
490     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
491
492     /* Test how the viewport affects clears */
493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
497
498     vp.X = 160;
499     vp.Y = 120;
500     vp.Width = 160;
501     vp.Height = 120;
502     vp.MinZ = 0.0;
503     vp.MaxZ = 1.0;
504     hr = IDirect3DDevice9_SetViewport(device, &vp);
505     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
508
509     vp.X = 320;
510     vp.Y = 240;
511     vp.Width = 320;
512     vp.Height = 240;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     rect[0].x1 = 160;
518     rect[0].y1 = 120;
519     rect[0].x2 = 480;
520     rect[0].y2 = 360;
521     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523
524     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
526
527     color = getPixelColor(device, 158, 118);
528     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529     color = getPixelColor(device, 162, 118);
530     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531     color = getPixelColor(device, 158, 122);
532     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533     color = getPixelColor(device, 162, 122);
534     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
535
536     color = getPixelColor(device, 318, 238);
537     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538     color = getPixelColor(device, 322, 238);
539     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540     color = getPixelColor(device, 318, 242);
541     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542     color = getPixelColor(device, 322, 242);
543     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
544
545     color = getPixelColor(device, 478, 358);
546     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547     color = getPixelColor(device, 482, 358);
548     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549     color = getPixelColor(device, 478, 362);
550     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551     color = getPixelColor(device, 482, 362);
552     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
553
554     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
555
556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
558
559     scissor.left = 160;
560     scissor.right = 480;
561     scissor.top = 120;
562     scissor.bottom = 360;
563     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
567
568     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
572
573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
575
576     color = getPixelColor(device, 158, 118);
577     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578     color = getPixelColor(device, 162, 118);
579     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580     color = getPixelColor(device, 158, 122);
581     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582     color = getPixelColor(device, 162, 122);
583     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
584
585     color = getPixelColor(device, 158, 358);
586     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587     color = getPixelColor(device, 162, 358);
588     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589     color = getPixelColor(device, 158, 358);
590     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591     color = getPixelColor(device, 162, 362);
592     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
593
594     color = getPixelColor(device, 478, 118);
595     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596     color = getPixelColor(device, 478, 122);
597     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598     color = getPixelColor(device, 482, 122);
599     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600     color = getPixelColor(device, 482, 358);
601     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
602
603     color = getPixelColor(device, 478, 358);
604     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605     color = getPixelColor(device, 478, 362);
606     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607     color = getPixelColor(device, 482, 358);
608     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609     color = getPixelColor(device, 482, 362);
610     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
611
612     color = getPixelColor(device, 318, 238);
613     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614     color = getPixelColor(device, 318, 242);
615     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616     color = getPixelColor(device, 322, 238);
617     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618     color = getPixelColor(device, 322, 242);
619     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
620
621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622
623     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
627
628     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
630
631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
633
634     /* Colorwriteenable does not affect the clear */
635     color = getPixelColor(device, 320, 240);
636     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
637
638     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
639 }
640
641 static void color_fill_test(IDirect3DDevice9 *device)
642 {
643     HRESULT hr;
644     IDirect3DSurface9 *backbuffer = NULL;
645     IDirect3DSurface9 *rt_surface = NULL;
646     IDirect3DSurface9 *offscreen_surface = NULL;
647     DWORD fill_color, color;
648
649     /* Test ColorFill on a the backbuffer (should pass) */
650     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652     if(backbuffer)
653     {
654         fill_color = 0x112233;
655         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
656
657         color = getPixelColor(device, 0, 0);
658         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
659
660         IDirect3DSurface9_Release(backbuffer);
661     }
662
663     /* Test ColorFill on a render target surface (should pass) */
664     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666     if(rt_surface)
667     {
668         fill_color = 0x445566;
669         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
670
671         color = getPixelColorFromSurface(rt_surface, 0, 0);
672         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
673
674         IDirect3DSurface9_Release(rt_surface);
675     }
676
677     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681     if(offscreen_surface)
682     {
683         fill_color = 0x778899;
684         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
685
686         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
688
689         IDirect3DSurface9_Release(offscreen_surface);
690     }
691
692     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693     offscreen_surface = NULL;
694     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697     if(offscreen_surface)
698     {
699         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
701
702         IDirect3DSurface9_Release(offscreen_surface);
703     }
704 }
705
706 typedef struct {
707     float in[4];
708     DWORD out;
709 } test_data_t;
710
711 /*
712  *  c7      mova    ARGB            mov     ARGB
713  * -2.4     -2      0x00ffff00      -3      0x00ff0000
714  * -1.6     -2      0x00ffff00      -2      0x00ffff00
715  * -0.4      0      0x0000ffff      -1      0x0000ff00
716  *  0.4      0      0x0000ffff       0      0x0000ffff
717  *  1.6      2      0x00ff00ff       1      0x000000ff
718  *  2.4      2      0x00ff00ff       2      0x00ff00ff
719  */
720 static void test_mova(IDirect3DDevice9 *device)
721 {
722     static const DWORD mova_test[] = {
723         0xfffe0200,                                                             /* vs_2_0                       */
724         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
725         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
726         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
727         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
728         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
729         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
730         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
731         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
732         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
733         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
734         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
735         0x0000ffff                                                              /* END                          */
736     };
737     static const DWORD mov_test[] = {
738         0xfffe0101,                                                             /* vs_1_1                       */
739         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
740         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
741         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
742         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
743         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
744         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
745         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
746         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
747         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
748         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
749         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
750         0x0000ffff                                                              /* END                          */
751     };
752
753     static const test_data_t test_data[2][6] = {
754         {
755             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
761         },
762         {
763             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
769         }
770     };
771
772     static const float quad[][3] = {
773         {-1.0f, -1.0f, 0.0f},
774         {-1.0f,  1.0f, 0.0f},
775         { 1.0f, -1.0f, 0.0f},
776         { 1.0f,  1.0f, 0.0f},
777     };
778
779     static const D3DVERTEXELEMENT9 decl_elements[] = {
780         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781         D3DDECL_END()
782     };
783
784     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785     IDirect3DVertexShader9 *mova_shader = NULL;
786     IDirect3DVertexShader9 *mov_shader = NULL;
787     HRESULT hr;
788     UINT i, j;
789
790     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
798
799     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801     for(j = 0; j < 2; ++j)
802     {
803         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
804         {
805             DWORD color;
806
807             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
809
810             hr = IDirect3DDevice9_BeginScene(device);
811             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
812
813             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
815
816             hr = IDirect3DDevice9_EndScene(device);
817             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
818
819             color = getPixelColor(device, 320, 240);
820             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
822
823             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
825
826             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
828         }
829         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
831     }
832
833     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
835
836     IDirect3DVertexDeclaration9_Release(vertex_declaration);
837     IDirect3DVertexShader9_Release(mova_shader);
838     IDirect3DVertexShader9_Release(mov_shader);
839 }
840
841 struct sVertex {
842     float x, y, z;
843     DWORD diffuse;
844     DWORD specular;
845 };
846
847 struct sVertexT {
848     float x, y, z, rhw;
849     DWORD diffuse;
850     DWORD specular;
851 };
852
853 static void fog_test(IDirect3DDevice9 *device)
854 {
855     HRESULT hr;
856     D3DCOLOR color;
857     float start = 0.0f, end = 1.0f;
858     D3DCAPS9 caps;
859     int i;
860
861     /* Gets full z based fog with linear fog, no fog with specular color */
862     struct sVertex unstransformed_1[] = {
863         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
864         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
865         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
866         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
867     };
868     /* Ok, I am too lazy to deal with transform matrices */
869     struct sVertex unstransformed_2[] = {
870         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
871         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
872         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
873         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
874     };
875     /* Untransformed ones. Give them a different diffuse color to make the test look
876      * nicer. It also makes making sure that they are drawn correctly easier.
877      */
878     struct sVertexT transformed_1[] = {
879         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
880         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
881         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
882         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
883     };
884     struct sVertexT transformed_2[] = {
885         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
886         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
887         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
888         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
889     };
890     struct vertex rev_fog_quads[] = {
891        {-1.0,   -1.0,   0.1,    0x000000ff},
892        {-1.0,    0.0,   0.1,    0x000000ff},
893        { 0.0,    0.0,   0.1,    0x000000ff},
894        { 0.0,   -1.0,   0.1,    0x000000ff},
895
896        { 0.0,   -1.0,   0.9,    0x000000ff},
897        { 0.0,    0.0,   0.9,    0x000000ff},
898        { 1.0,    0.0,   0.9,    0x000000ff},
899        { 1.0,   -1.0,   0.9,    0x000000ff},
900
901        { 0.0,    0.0,   0.4,    0x000000ff},
902        { 0.0,    1.0,   0.4,    0x000000ff},
903        { 1.0,    1.0,   0.4,    0x000000ff},
904        { 1.0,    0.0,   0.4,    0x000000ff},
905
906        {-1.0,    0.0,   0.7,    0x000000ff},
907        {-1.0,    1.0,   0.7,    0x000000ff},
908        { 0.0,    1.0,   0.7,    0x000000ff},
909        { 0.0,    0.0,   0.7,    0x000000ff},
910     };
911     WORD Indices[] = {0, 1, 2, 2, 3, 0};
912
913     memset(&caps, 0, sizeof(caps));
914     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
918
919     /* Setup initial states: No lighting, fog on, fog color */
920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
926
927     /* First test: Both table fog and vertex fog off */
928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
932
933     /* Start = 0, end = 1. Should be default, but set them */
934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
938
939     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
940     {
941         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946                                                      sizeof(unstransformed_1[0]));
947         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
948
949         /* That makes it use the Z value */
950         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952         /* Untransformed, vertex fog != none (or table fog != none):
953          * Use the Z value as input into the equation
954          */
955         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957                                                      sizeof(unstransformed_1[0]));
958         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959
960         /* transformed verts */
961         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966                                                      sizeof(transformed_1[0]));
967         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
968
969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972          * equation
973          */
974         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976                                                      sizeof(transformed_2[0]));
977         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
978
979         hr = IDirect3DDevice9_EndScene(device);
980         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
981     }
982     else
983     {
984         ok(FALSE, "BeginScene failed\n");
985     }
986
987     color = getPixelColor(device, 160, 360);
988     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989     color = getPixelColor(device, 160, 120);
990     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991     color = getPixelColor(device, 480, 120);
992     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
994     {
995         color = getPixelColor(device, 480, 360);
996         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
997     }
998     else
999     {
1000         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001          * The settings above result in no fogging with vertex fog
1002          */
1003         color = getPixelColor(device, 480, 120);
1004         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005         trace("Info: Table fog not supported by this device\n");
1006     }
1007     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1008
1009     /* Now test the special case fogstart == fogend */
1010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1012
1013     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1014     {
1015         start = 512;
1016         end = 512;
1017         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1021
1022         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1028
1029         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033          * color and has fixed fogstart and fogend.
1034          */
1035         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037                 sizeof(unstransformed_1[0]));
1038         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041                 sizeof(unstransformed_1[0]));
1042         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1043
1044         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049                 sizeof(transformed_1[0]));
1050         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1051
1052         hr = IDirect3DDevice9_EndScene(device);
1053         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1054     }
1055     else
1056     {
1057         ok(FALSE, "BeginScene failed\n");
1058     }
1059     color = getPixelColor(device, 160, 360);
1060     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061     color = getPixelColor(device, 160, 120);
1062     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063     color = getPixelColor(device, 480, 120);
1064     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066
1067     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068      * but without shaders it seems to work everywhere
1069      */
1070     end = 0.2;
1071     start = 0.8;
1072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1078
1079     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081      * so skip this for now
1082      */
1083     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084         const char *mode = (i ? "table" : "vertex");
1085         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091         hr = IDirect3DDevice9_BeginScene(device);
1092         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093         if(SUCCEEDED(hr)) {
1094             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1095                                 4,  5,  6,  6,  7, 4,
1096                                 8,  9, 10, 10, 11, 8,
1097                             12, 13, 14, 14, 15, 12};
1098
1099             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101                     sizeof(rev_fog_quads[0]));
1102             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1103
1104             hr = IDirect3DDevice9_EndScene(device);
1105             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1106         }
1107         color = getPixelColor(device, 160, 360);
1108         ok(color_match(color, 0x0000ff00, 1),
1109                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1110
1111         color = getPixelColor(device, 160, 120);
1112         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1114
1115         color = getPixelColor(device, 480, 120);
1116         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1118
1119         color = getPixelColor(device, 480, 360);
1120         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1121
1122         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1123
1124         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126             break;
1127         }
1128     }
1129     /* Turn off the fog master switch to avoid confusing other tests */
1130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132     start = 0.0;
1133     end = 1.0;
1134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1142 }
1143
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146  * regardless of the actual addressing mode set. The way this test works is
1147  * that we sample in one of the corners of the cubemap with filtering enabled,
1148  * and check the interpolated color. There are essentially two reasonable
1149  * things an implementation can do: Either pick one of the faces and
1150  * interpolate the edge texel with itself (i.e., clamp within the face), or
1151  * interpolate between the edge texels of the three involved faces. It should
1152  * never involve the border color or the other side (texcoord wrapping) of a
1153  * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1155 {
1156     static const float quad[][6] = {
1157         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1161     };
1162
1163     static const D3DVERTEXELEMENT9 decl_elements[] = {
1164         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166         D3DDECL_END()
1167     };
1168
1169     static const struct {
1170         D3DTEXTUREADDRESS mode;
1171         const char *name;
1172     } address_modes[] = {
1173         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1178     };
1179
1180     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181     IDirect3DCubeTexture9 *texture = NULL;
1182     IDirect3DSurface9 *surface = NULL;
1183     IDirect3DSurface9 *face_surface;
1184     D3DLOCKED_RECT locked_rect;
1185     HRESULT hr;
1186     UINT x;
1187     INT y, face;
1188
1189     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1193
1194     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1197
1198     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199             D3DPOOL_DEFAULT, &texture, NULL);
1200     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1201
1202     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1204
1205     for (y = 0; y < 128; ++y)
1206     {
1207         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208         for (x = 0; x < 64; ++x)
1209         {
1210             *ptr++ = 0xff0000ff;
1211         }
1212         for (x = 64; x < 128; ++x)
1213         {
1214             *ptr++ = 0xffff0000;
1215         }
1216     }
1217
1218     hr = IDirect3DSurface9_UnlockRect(surface);
1219     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1220
1221     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1223
1224     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1226
1227     IDirect3DSurface9_Release(face_surface);
1228
1229     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1231
1232     for (y = 0; y < 128; ++y)
1233     {
1234         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235         for (x = 0; x < 64; ++x)
1236         {
1237             *ptr++ = 0xffff0000;
1238         }
1239         for (x = 64; x < 128; ++x)
1240         {
1241             *ptr++ = 0xff0000ff;
1242         }
1243     }
1244
1245     hr = IDirect3DSurface9_UnlockRect(surface);
1246     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1247
1248     /* Create cube faces */
1249     for (face = 1; face < 6; ++face)
1250     {
1251         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1253
1254         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1256
1257         IDirect3DSurface9_Release(face_surface);
1258     }
1259
1260     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1262
1263     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1269
1270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1272
1273     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1274     {
1275         DWORD color;
1276
1277         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1281
1282         hr = IDirect3DDevice9_BeginScene(device);
1283         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1284
1285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1287
1288         hr = IDirect3DDevice9_EndScene(device);
1289         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1290
1291         color = getPixelColor(device, 320, 240);
1292         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294                 color, address_modes[x].name);
1295
1296         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1298
1299         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1301     }
1302
1303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1305
1306     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307     IDirect3DCubeTexture9_Release(texture);
1308     IDirect3DSurface9_Release(surface);
1309 }
1310
1311 static void offscreen_test(IDirect3DDevice9 *device)
1312 {
1313     HRESULT hr;
1314     IDirect3DTexture9 *offscreenTexture = NULL;
1315     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316     DWORD color;
1317
1318     static const float quad[][5] = {
1319         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1321         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1323     };
1324
1325     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1327
1328     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330     if(!offscreenTexture) {
1331         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334         if(!offscreenTexture) {
1335             skip("Cannot create an offscreen render target\n");
1336             goto out;
1337         }
1338     }
1339
1340     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342     if(!backbuffer) {
1343         goto out;
1344     }
1345
1346     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348     if(!offscreen) {
1349         goto out;
1350     }
1351
1352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1354
1355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1365
1366     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1371
1372         /* Draw without textures - Should result in a white quad */
1373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1375
1376         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1380
1381         /* This time with the texture */
1382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1384
1385         IDirect3DDevice9_EndScene(device);
1386     }
1387
1388     /* Center quad - should be white */
1389     color = getPixelColor(device, 320, 240);
1390     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391     /* Some quad in the cleared part of the texture */
1392     color = getPixelColor(device, 170, 240);
1393     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394     /* Part of the originally cleared back buffer */
1395     color = getPixelColor(device, 10, 10);
1396     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397     if(0) {
1398         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400          * the offscreen rendering mode this test would succeed or fail
1401          */
1402         color = getPixelColor(device, 10, 470);
1403         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1404     }
1405
1406     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1407
1408 out:
1409     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1411
1412     /* restore things */
1413     if(backbuffer) {
1414         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416         IDirect3DSurface9_Release(backbuffer);
1417     }
1418     if(offscreenTexture) {
1419         IDirect3DTexture9_Release(offscreenTexture);
1420     }
1421     if(offscreen) {
1422         IDirect3DSurface9_Release(offscreen);
1423     }
1424 }
1425
1426 /* This test tests fog in combination with shaders.
1427  * What's tested: linear fog (vertex and table) with pixel shader
1428  *                linear table fog with non foggy vertex shader
1429  *                vertex fog with foggy vertex shader, non-linear
1430  *                fog with shader, non-linear fog with foggy shader,
1431  *                linear table fog with foggy shader
1432  */
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1434 {
1435     HRESULT hr;
1436     DWORD color;
1437     union {
1438         float f;
1439         DWORD i;
1440     } start, end;
1441     unsigned int i, j;
1442
1443     /* basic vertex shader without fog computation ("non foggy") */
1444     static const DWORD vertex_shader_code1[] = {
1445         0xfffe0101,                                                             /* vs_1_1                       */
1446         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1447         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1448         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1449         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1450         0x0000ffff
1451     };
1452     /* basic vertex shader with reversed fog computation ("foggy") */
1453     static const DWORD vertex_shader_code2[] = {
1454         0xfffe0101,                                                             /* vs_1_1                        */
1455         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1456         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1457         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1459         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1460         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1461         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1462         0x0000ffff
1463     };
1464     /* basic pixel shader */
1465     static const DWORD pixel_shader_code[] = {
1466         0xffff0101,                                                             /* ps_1_1     */
1467         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1468         0x0000ffff
1469     };
1470
1471     static struct vertex quad[] = {
1472         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1473         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1474         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1475         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1476     };
1477
1478     static const D3DVERTEXELEMENT9 decl_elements[] = {
1479         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1481         D3DDECL_END()
1482     };
1483
1484     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1486     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1487
1488     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489     static const struct test_data_t {
1490         int vshader;
1491         int pshader;
1492         D3DFOGMODE vfog;
1493         D3DFOGMODE tfog;
1494         unsigned int color[11];
1495     } test_data[] = {
1496         /* only pixel shader: */
1497         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512
1513         /* vertex shader */
1514         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1523
1524         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader and pixel shader */
1532         /* The next 4 tests would read the fog coord output, but it isn't available.
1533          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535          * These tests should be disabled if some other hardware behaves differently
1536          */
1537         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1549
1550         /* These use the Z coordinate with linear table fog */
1551         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1563
1564         /* Non-linear table fog without fog coord */
1565         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1571
1572 #if 0  /* FIXME: these fail on GeForce 8500 */
1573         /* foggy vertex shader */
1574         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1587
1588         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589          * all using the fixed fog-coord linear fog
1590          */
1591         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1603
1604         /* These use table fog. Here the shader-provided fog coordinate is
1605          * ignored and the z coordinate used instead
1606          */
1607         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1616     };
1617
1618     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619     start.f=0.1f;
1620     end.f=0.9f;
1621
1622     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1630
1631     /* Setup initial states: No lighting, fog on, fog color */
1632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1640
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1645
1646     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1651
1652     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1653     {
1654         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1662
1663         for(j=0; j < 11; j++)
1664         {
1665             /* Don't use the whole zrange to prevent rounding errors */
1666             quad[0].z = 0.001f + (float)j / 10.02f;
1667             quad[1].z = 0.001f + (float)j / 10.02f;
1668             quad[2].z = 0.001f + (float)j / 10.02f;
1669             quad[3].z = 0.001f + (float)j / 10.02f;
1670
1671             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1673
1674             hr = IDirect3DDevice9_BeginScene(device);
1675             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1676
1677             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1679
1680             hr = IDirect3DDevice9_EndScene(device);
1681             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1682
1683             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684             color = getPixelColor(device, 128, 240);
1685             ok(color_match(color, test_data[i].color[j], 13),
1686                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1688
1689             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1690         }
1691     }
1692
1693     /* reset states */
1694     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1702
1703     IDirect3DVertexShader9_Release(vertex_shader[1]);
1704     IDirect3DVertexShader9_Release(vertex_shader[2]);
1705     IDirect3DPixelShader9_Release(pixel_shader[1]);
1706     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1707 }
1708
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710     unsigned int i, x, y;
1711     HRESULT hr;
1712     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713     D3DLOCKED_RECT locked_rect;
1714
1715     /* Generate the textures */
1716     for(i=0; i<2; i++)
1717     {
1718         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719                                             D3DPOOL_MANAGED, &texture[i], NULL);
1720         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1721
1722         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724         for (y = 0; y < 128; ++y)
1725         {
1726             if(i)
1727             { /* Set up black texture with 2x2 texel white spot in the middle */
1728                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729                 for (x = 0; x < 128; ++x)
1730                 {
1731                     if(y>62 && y<66 && x>62 && x<66)
1732                         *ptr++ = 0xffffffff;
1733                     else
1734                         *ptr++ = 0xff000000;
1735                 }
1736             }
1737             else
1738             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739                * (if multiplied with bumpenvmat)
1740               */
1741                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742                 for (x = 0; x < 128; ++x)
1743                 {
1744                     if(abs(x-64)>abs(y-64))
1745                     {
1746                         if(x < 64)
1747                             *ptr++ = 0xc000;
1748                         else
1749                             *ptr++ = 0x4000;
1750                     }
1751                     else
1752                     {
1753                         if(y < 64)
1754                             *ptr++ = 0x0040;
1755                         else
1756                             *ptr++ = 0x00c0;
1757                     }
1758                 }
1759             }
1760         }
1761         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1763
1764         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1766
1767         /* Disable texture filtering */
1768         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1772
1773         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1777     }
1778 }
1779
1780 /* test the behavior of the texbem instruction
1781  * with normal 2D and projective 2D textures
1782  */
1783 static void texbem_test(IDirect3DDevice9 *device)
1784 {
1785     HRESULT hr;
1786     DWORD color;
1787     int i;
1788
1789     static const DWORD pixel_shader_code[] = {
1790         0xffff0101,                         /* ps_1_1*/
1791         0x00000042, 0xb00f0000,             /* tex t0*/
1792         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794         0x0000ffff
1795     };
1796     static const DWORD double_texbem_code[] =  {
1797         0xffff0103,                                         /* ps_1_3           */
1798         0x00000042, 0xb00f0000,                             /* tex t0           */
1799         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1800         0x00000042, 0xb00f0002,                             /* tex t2           */
1801         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1802         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1803         0x0000ffff                                          /* end              */
1804     };
1805
1806
1807     static const float quad[][7] = {
1808         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1812     };
1813     static const float quad_proj[][9] = {
1814         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1815         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1816         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1817         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1818     };
1819
1820     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824         D3DDECL_END()
1825     },{
1826         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829         D3DDECL_END()
1830     } };
1831
1832     /* use asymmetric matrix to test loading */
1833     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1834
1835     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836     IDirect3DPixelShader9       *pixel_shader       = NULL;
1837     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1838     D3DLOCKED_RECT locked_rect;
1839
1840     generate_bumpmap_textures(device);
1841
1842     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1847
1848     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1850
1851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1853
1854     for(i=0; i<2; i++)
1855     {
1856         if(i)
1857         {
1858             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1860         }
1861
1862         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1866
1867         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1871
1872         hr = IDirect3DDevice9_BeginScene(device);
1873         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874
1875         if(!i)
1876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877         else
1878             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1880
1881         hr = IDirect3DDevice9_EndScene(device);
1882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1883
1884         color = getPixelColor(device, 320-32, 240);
1885         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886         color = getPixelColor(device, 320+32, 240);
1887         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888         color = getPixelColor(device, 320, 240-32);
1889         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890         color = getPixelColor(device, 320, 240+32);
1891         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1892
1893         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1895
1896         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898         IDirect3DPixelShader9_Release(pixel_shader);
1899
1900         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1903     }
1904
1905     /* clean up */
1906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1908
1909     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1911
1912     for(i=0; i<2; i++)
1913     {
1914         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919         IDirect3DTexture9_Release(texture);
1920     }
1921
1922     /* Test double texbem */
1923     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1931
1932     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1936
1937     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1939
1940     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1946
1947     {
1948         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex  0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952         static const DWORD pixel_data[] = {
1953             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1958             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1961         };
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1965
1966         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968         for(i = 0; i < 8; i++) {
1969             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1970         }
1971         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1973     }
1974
1975     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1987
1988     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1989     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1998
1999     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2000     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2001     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009
2010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2026
2027     hr = IDirect3DDevice9_BeginScene(device);
2028     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029     if(SUCCEEDED(hr)) {
2030         static const float double_quad[] = {
2031             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2032              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2033             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2034              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2035         };
2036
2037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039         hr = IDirect3DDevice9_EndScene(device);
2040         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2041     }
2042     color = getPixelColor(device, 320, 240);
2043     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2044
2045     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2055
2056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2058
2059     IDirect3DPixelShader9_Release(pixel_shader);
2060     IDirect3DTexture9_Release(texture);
2061     IDirect3DTexture9_Release(texture1);
2062     IDirect3DTexture9_Release(texture2);
2063 }
2064
2065 static void z_range_test(IDirect3DDevice9 *device)
2066 {
2067     const struct vertex quad[] =
2068     {
2069         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2070         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2071         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2072         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2073     };
2074     const struct vertex quad2[] =
2075     {
2076         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2077         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2078         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2079         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2080     };
2081
2082     const struct tvertex quad3[] =
2083     {
2084         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2085         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2086         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2087         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2088     };
2089     const struct tvertex quad4[] =
2090     {
2091         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2092         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2093         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2094         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2095     };
2096     HRESULT hr;
2097     DWORD color;
2098     IDirect3DVertexShader9 *shader;
2099     IDirect3DVertexDeclaration9 *decl;
2100     D3DCAPS9 caps;
2101     const DWORD shader_code[] = {
2102         0xfffe0101,                                     /* vs_1_1           */
2103         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2104         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2105         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2106         0x0000ffff                                      /* end              */
2107     };
2108     static const D3DVERTEXELEMENT9 decl_elements[] = {
2109         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110         D3DDECL_END()
2111     };
2112     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113      * then call Present. Then clear the color buffer to make sure it has some defined content
2114      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115      * by the depth value.
2116      */
2117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2123
2124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2134
2135     hr = IDirect3DDevice9_BeginScene(device);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137     if(hr == D3D_OK)
2138     {
2139         /* Test the untransformed vertex path */
2140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2146
2147         /* Test the transformed vertex path */
2148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2150
2151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2157
2158         hr = IDirect3DDevice9_EndScene(device);
2159         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2160     }
2161
2162     /* Do not test the exact corner pixels, but go pretty close to them */
2163
2164     /* Clipped because z > 1.0 */
2165     color = getPixelColor(device, 28, 238);
2166     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167     color = getPixelColor(device, 28, 241);
2168     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2169
2170     /* Not clipped, > z buffer clear value(0.75) */
2171     color = getPixelColor(device, 31, 238);
2172     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173     color = getPixelColor(device, 31, 241);
2174     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175     color = getPixelColor(device, 100, 238);
2176     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177     color = getPixelColor(device, 100, 241);
2178     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2179
2180     /* Not clipped, < z buffer clear value */
2181     color = getPixelColor(device, 104, 238);
2182     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183     color = getPixelColor(device, 104, 241);
2184     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185     color = getPixelColor(device, 318, 238);
2186     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187     color = getPixelColor(device, 318, 241);
2188     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2189
2190     /* Clipped because z < 0.0 */
2191     color = getPixelColor(device, 321, 238);
2192     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193     color = getPixelColor(device, 321, 241);
2194     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2195
2196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2198
2199     /* Test the shader path */
2200     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202         skip("Vertex shaders not supported\n");
2203         goto out;
2204     }
2205     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2209
2210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2211
2212     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214     IDirect3DDevice9_SetVertexShader(device, shader);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2216
2217     hr = IDirect3DDevice9_BeginScene(device);
2218     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219     if(hr == D3D_OK)
2220     {
2221         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2231
2232         hr = IDirect3DDevice9_EndScene(device);
2233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2234     }
2235
2236     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238     IDirect3DDevice9_SetVertexShader(device, NULL);
2239     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2240
2241     IDirect3DVertexDeclaration9_Release(decl);
2242     IDirect3DVertexShader9_Release(shader);
2243
2244     /* Z < 1.0 */
2245     color = getPixelColor(device, 28, 238);
2246     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2247
2248     /* 1.0 < z < 0.75 */
2249     color = getPixelColor(device, 31, 238);
2250     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251     color = getPixelColor(device, 100, 238);
2252     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2253
2254     /* 0.75 < z < 0.0 */
2255     color = getPixelColor(device, 104, 238);
2256     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257     color = getPixelColor(device, 318, 238);
2258     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2259
2260     /* 0.0 < z */
2261     color = getPixelColor(device, 321, 238);
2262     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2263
2264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2266
2267     out:
2268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2274 }
2275
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2277 {
2278     D3DSURFACE_DESC desc;
2279     D3DLOCKED_RECT l;
2280     HRESULT hr;
2281     unsigned int x, y;
2282     DWORD *mem;
2283
2284     memset(&desc, 0, sizeof(desc));
2285     memset(&l, 0, sizeof(l));
2286     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290     if(FAILED(hr)) return;
2291
2292     for(y = 0; y < desc.Height; y++)
2293     {
2294         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2296         {
2297             mem[x] = color;
2298         }
2299     }
2300     hr = IDirect3DSurface9_UnlockRect(surface);
2301     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2302 }
2303
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2306 {
2307     HRESULT hr;
2308     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315     IDirect3DSurface9 *orig_rt = NULL;
2316     IDirect3DSurface9 *backbuffer = NULL;
2317     DWORD color;
2318
2319     RECT src_rect64 = {0, 0, 64, 64};
2320     RECT src_rect64_flipy = {0, 64, 64, 0};
2321     RECT dst_rect64 = {0, 0, 64, 64};
2322     RECT dst_rect64_flipy = {0, 64, 64, 0};
2323
2324     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326     if(!orig_rt) {
2327         goto out;
2328     }
2329
2330     /* Create our temporary surfaces in system memory */
2331     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2335
2336     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2343
2344     /* Create render target surfaces */
2345     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2353
2354     /* Create render target textures */
2355     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363     if (tex_rt32) {
2364         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2366     }
2367     if (tex_rt64) {
2368         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2370     }
2371     if (tex_rt_dest64) {
2372         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2374     }
2375     if (tex_rt_dest64) {
2376         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2378     }
2379
2380     /* Create regular textures in D3DPOOL_DEFAULT */
2381     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387     if (tex32) {
2388         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2390     }
2391     if (tex64) {
2392         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2394     }
2395     if (tex_dest64) {
2396         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2398     }
2399
2400     /*********************************************************************
2401      * Tests for when the source parameter is an offscreen plain surface *
2402      *********************************************************************/
2403
2404     /* Fill the offscreen 64x64 surface with green */
2405     if (surf_offscreen64)
2406         fill_surface(surf_offscreen64, 0xff00ff00);
2407
2408     /* offscreenplain ==> offscreenplain, same size */
2409     if(surf_offscreen64 && surf_offscreen_dest64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412
2413         if (hr == D3D_OK) {
2414             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2416         }
2417
2418         /* Blit without scaling */
2419         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2421
2422         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2425
2426         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429     }
2430
2431     /* offscreenplain ==> rendertarget texture, same size */
2432     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2435
2436         /* We can't lock rendertarget textures, so copy to our temp surface first */
2437         if (hr == D3D_OK) {
2438             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2440         }
2441
2442         if (hr == D3D_OK) {
2443             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2445         }
2446
2447         /* Blit without scaling */
2448         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450
2451         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454
2455         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458     }
2459
2460     /* offscreenplain ==> rendertarget surface, same size */
2461     if(surf_offscreen64 && surf_rt_dest64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2464
2465         if (hr == D3D_OK) {
2466             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2468         }
2469
2470         /* Blit without scaling */
2471         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2473
2474         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2481     }
2482
2483     /* offscreenplain ==> texture, same size (should fail) */
2484     if(surf_offscreen64 && surf_tex_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2487     }
2488
2489     /* Fill the smaller offscreen surface with red */
2490     fill_surface(surf_offscreen32, 0xffff0000);
2491
2492     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493     if(surf_offscreen32 && surf_offscreen64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2496     }
2497
2498     /* offscreenplain ==> rendertarget texture, scaling */
2499     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2502
2503         /* We can't lock rendertarget textures, so copy to our temp surface first */
2504         if (hr == D3D_OK) {
2505             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2507         }
2508
2509         if (hr == D3D_OK) {
2510             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2512         }
2513     }
2514
2515     /* offscreenplain ==> rendertarget surface, scaling */
2516     if(surf_offscreen32 && surf_rt_dest64) {
2517         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2519
2520         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2522     }
2523
2524     /* offscreenplain ==> texture, scaling (should fail) */
2525     if(surf_offscreen32 && surf_tex_dest64) {
2526         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2528     }
2529
2530     /************************************************************
2531      * Tests for when the source parameter is a regular texture *
2532      ************************************************************/
2533
2534     /* Fill the surface of the regular texture with blue */
2535     if (surf_tex64 && surf_temp64) {
2536         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537         fill_surface(surf_temp64, 0xff0000ff);
2538         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2540     }
2541
2542     /* texture ==> offscreenplain, same size */
2543     if(surf_tex64 && surf_offscreen64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /* texture ==> rendertarget texture, same size */
2549     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2552
2553         /* We can't lock rendertarget textures, so copy to our temp surface first */
2554         if (hr == D3D_OK) {
2555             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2557         }
2558
2559         if (hr == D3D_OK) {
2560             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2562         }
2563
2564         /* Blit without scaling */
2565         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2567
2568         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571
2572         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2575     }
2576
2577     /* texture ==> rendertarget surface, same size */
2578     if(surf_tex64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         if (hr == D3D_OK) {
2583             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2585         }
2586
2587         /* Blit without scaling */
2588         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590
2591         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2594
2595         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2598     }
2599
2600     /* texture ==> texture, same size (should fail) */
2601     if(surf_tex64 && surf_tex_dest64) {
2602         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2604     }
2605
2606     /* Fill the surface of the smaller regular texture with red */
2607     if (surf_tex32 && surf_temp32) {
2608         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609         fill_surface(surf_temp32, 0xffff0000);
2610         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2612     }
2613
2614     /* texture ==> offscreenplain, scaling (should fail) */
2615     if(surf_tex32 && surf_offscreen64) {
2616         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2618     }
2619
2620     /* texture ==> rendertarget texture, scaling */
2621     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624
2625         /* We can't lock rendertarget textures, so copy to our temp surface first */
2626         if (hr == D3D_OK) {
2627             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2629         }
2630
2631         if (hr == D3D_OK) {
2632             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2634         }
2635     }
2636
2637     /* texture ==> rendertarget surface, scaling */
2638     if(surf_tex32 && surf_rt_dest64) {
2639         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2641
2642         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2644     }
2645
2646     /* texture ==> texture, scaling (should fail) */
2647     if(surf_tex32 && surf_tex_dest64) {
2648         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2650     }
2651
2652     /*****************************************************************
2653      * Tests for when the source parameter is a rendertarget texture *
2654      *****************************************************************/
2655
2656     /* Fill the surface of the rendertarget texture with white */
2657     if (surf_tex_rt64 && surf_temp64) {
2658         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659         fill_surface(surf_temp64, 0xffffffff);
2660         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2662     }
2663
2664     /* rendertarget texture ==> offscreenplain, same size */
2665     if(surf_tex_rt64 && surf_offscreen64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /* rendertarget texture ==> rendertarget texture, same size */
2671     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2674
2675         /* We can't lock rendertarget textures, so copy to our temp surface first */
2676         if (hr == D3D_OK) {
2677             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2679         }
2680
2681         if (hr == D3D_OK) {
2682             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2684         }
2685
2686         /* Blit without scaling */
2687         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2689
2690         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693
2694         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2697     }
2698
2699     /* rendertarget texture ==> rendertarget surface, same size */
2700     if(surf_tex_rt64 && surf_rt_dest64) {
2701         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703
2704         if (hr == D3D_OK) {
2705             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2707         }
2708
2709         /* Blit without scaling */
2710         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2712
2713         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2716
2717         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720     }
2721
2722     /* rendertarget texture ==> texture, same size (should fail) */
2723     if(surf_tex_rt64 && surf_tex_dest64) {
2724         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2726     }
2727
2728     /* Fill the surface of the smaller rendertarget texture with red */
2729     if (surf_tex_rt32 && surf_temp32) {
2730         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731         fill_surface(surf_temp32, 0xffff0000);
2732         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2734     }
2735
2736     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737     if(surf_tex_rt32 && surf_offscreen64) {
2738         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2740     }
2741
2742     /* rendertarget texture ==> rendertarget texture, scaling */
2743     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746
2747         /* We can't lock rendertarget textures, so copy to our temp surface first */
2748         if (hr == D3D_OK) {
2749             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2751         }
2752
2753         if (hr == D3D_OK) {
2754             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2756         }
2757     }
2758
2759     /* rendertarget texture ==> rendertarget surface, scaling */
2760     if(surf_tex_rt32 && surf_rt_dest64) {
2761         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763
2764         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2766     }
2767
2768     /* rendertarget texture ==> texture, scaling (should fail) */
2769     if(surf_tex_rt32 && surf_tex_dest64) {
2770         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2772     }
2773
2774     /*****************************************************************
2775      * Tests for when the source parameter is a rendertarget surface *
2776      *****************************************************************/
2777
2778     /* Fill the surface of the rendertarget surface with black */
2779     if (surf_rt64)
2780         fill_surface(surf_rt64, 0xff000000);
2781
2782     /* rendertarget texture ==> offscreenplain, same size */
2783     if(surf_rt64 && surf_offscreen64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2786     }
2787
2788     /* rendertarget surface ==> rendertarget texture, same size */
2789     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792
2793         /* We can't lock rendertarget textures, so copy to our temp surface first */
2794         if (hr == D3D_OK) {
2795             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2797         }
2798
2799         if (hr == D3D_OK) {
2800             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2802         }
2803
2804         /* Blit without scaling */
2805         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2807
2808         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2811
2812         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2815     }
2816
2817     /* rendertarget surface ==> rendertarget surface, same size */
2818     if(surf_rt64 && surf_rt_dest64) {
2819         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2821
2822         if (hr == D3D_OK) {
2823             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2825         }
2826
2827         /* Blit without scaling */
2828         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830
2831         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834
2835         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838     }
2839
2840     /* rendertarget surface ==> texture, same size (should fail) */
2841     if(surf_rt64 && surf_tex_dest64) {
2842         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2844     }
2845
2846     /* Fill the surface of the smaller rendertarget texture with red */
2847     if (surf_rt32)
2848         fill_surface(surf_rt32, 0xffff0000);
2849
2850     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851     if(surf_rt32 && surf_offscreen64) {
2852         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2854     }
2855
2856     /* rendertarget surface ==> rendertarget texture, scaling */
2857     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860
2861         /* We can't lock rendertarget textures, so copy to our temp surface first */
2862         if (hr == D3D_OK) {
2863             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2865         }
2866
2867         if (hr == D3D_OK) {
2868             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2870         }
2871     }
2872
2873     /* rendertarget surface ==> rendertarget surface, scaling */
2874     if(surf_rt32 && surf_rt_dest64) {
2875         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2877
2878         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2880     }
2881
2882     /* rendertarget surface ==> texture, scaling (should fail) */
2883     if(surf_rt32 && surf_tex_dest64) {
2884         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2886     }
2887
2888     /* backbuffer ==> surface tests (no scaling) */
2889     if(backbuffer && surf_tex_rt_dest640_480)
2890     {
2891         RECT src_rect = {0, 0, 640, 480};
2892         RECT src_rect_flipy = {0, 480, 640, 0};
2893         RECT dst_rect = {0, 0, 640, 480};
2894         RECT dst_rect_flipy = {0, 480, 640, 0};
2895
2896         /* Blit with NULL rectangles */
2897         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2899
2900         /* Blit without scaling */
2901         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2903
2904         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2907
2908         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2911     }
2912
2913     /* TODO: Test format conversions */
2914
2915
2916 out:
2917     /* Clean up */
2918     if (backbuffer)
2919         IDirect3DSurface9_Release(backbuffer);
2920     if (surf_rt32)
2921         IDirect3DSurface9_Release(surf_rt32);
2922     if (surf_rt64)
2923         IDirect3DSurface9_Release(surf_rt64);
2924     if (surf_rt_dest64)
2925         IDirect3DSurface9_Release(surf_rt_dest64);
2926     if (surf_temp32)
2927         IDirect3DSurface9_Release(surf_temp32);
2928     if (surf_temp64)
2929         IDirect3DSurface9_Release(surf_temp64);
2930     if (surf_offscreen32)
2931         IDirect3DSurface9_Release(surf_offscreen32);
2932     if (surf_offscreen64)
2933         IDirect3DSurface9_Release(surf_offscreen64);
2934     if (surf_offscreen_dest64)
2935         IDirect3DSurface9_Release(surf_offscreen_dest64);
2936
2937     if (tex_rt32) {
2938         if (surf_tex_rt32)
2939             IDirect3DSurface9_Release(surf_tex_rt32);
2940         IDirect3DTexture9_Release(tex_rt32);
2941     }
2942     if (tex_rt64) {
2943         if (surf_tex_rt64)
2944             IDirect3DSurface9_Release(surf_tex_rt64);
2945         IDirect3DTexture9_Release(tex_rt64);
2946     }
2947     if (tex_rt_dest64) {
2948         if (surf_tex_rt_dest64)
2949             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950         IDirect3DTexture9_Release(tex_rt_dest64);
2951     }
2952     if (tex_rt_dest640_480) {
2953         if (surf_tex_rt_dest640_480)
2954             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955         IDirect3DTexture9_Release(tex_rt_dest640_480);
2956     }
2957     if (tex32) {
2958         if (surf_tex32)
2959             IDirect3DSurface9_Release(surf_tex32);
2960         IDirect3DTexture9_Release(tex32);
2961     }
2962     if (tex64) {
2963         if (surf_tex64)
2964             IDirect3DSurface9_Release(surf_tex64);
2965         IDirect3DTexture9_Release(tex64);
2966     }
2967     if (tex_dest64) {
2968         if (surf_tex_dest64)
2969             IDirect3DSurface9_Release(surf_tex_dest64);
2970         IDirect3DTexture9_Release(tex_dest64);
2971     }
2972
2973     if (orig_rt) {
2974         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976         IDirect3DSurface9_Release(orig_rt);
2977     }
2978 }
2979
2980 static void maxmip_test(IDirect3DDevice9 *device)
2981 {
2982     IDirect3DTexture9 *texture = NULL;
2983     IDirect3DSurface9 *surface = NULL;
2984     HRESULT hr;
2985     DWORD color;
2986     const float quads[] = {
2987         -1.0,   -1.0,   0.0,    0.0,    0.0,
2988         -1.0,    0.0,   0.0,    0.0,    1.0,
2989          0.0,   -1.0,   0.0,    1.0,    0.0,
2990          0.0,    0.0,   0.0,    1.0,    1.0,
2991
2992          0.0,   -1.0,   0.0,    0.0,    0.0,
2993          0.0,    0.0,   0.0,    0.0,    1.0,
2994          1.0,   -1.0,   0.0,    1.0,    0.0,
2995          1.0,    0.0,   0.0,    1.0,    1.0,
2996
2997          0.0,    0.0,   0.0,    0.0,    0.0,
2998          0.0,    1.0,   0.0,    0.0,    1.0,
2999          1.0,    0.0,   0.0,    1.0,    0.0,
3000          1.0,    1.0,   0.0,    1.0,    1.0,
3001
3002         -1.0,    0.0,   0.0,    0.0,    0.0,
3003         -1.0,    1.0,   0.0,    0.0,    1.0,
3004          0.0,    0.0,   0.0,    1.0,    0.0,
3005          0.0,    1.0,   0.0,    1.0,    1.0,
3006     };
3007
3008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3010
3011     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3012                                         &texture, NULL);
3013     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3014     if(!texture)
3015     {
3016         skip("Failed to create test texture\n");
3017         return;
3018     }
3019
3020     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3021     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3022     fill_surface(surface, 0xffff0000);
3023     IDirect3DSurface9_Release(surface);
3024     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3025     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3026     fill_surface(surface, 0xff00ff00);
3027     IDirect3DSurface9_Release(surface);
3028     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3029     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3030     fill_surface(surface, 0xff0000ff);
3031     IDirect3DSurface9_Release(surface);
3032
3033     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
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_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3039     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3040
3041     hr = IDirect3DDevice9_BeginScene(device);
3042     if(SUCCEEDED(hr))
3043     {
3044         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3045         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3046         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3047         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3048
3049         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3050         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3051         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3052         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3053
3054         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3055         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3057         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3058
3059         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3060         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3062         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063         hr = IDirect3DDevice9_EndScene(device);
3064         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3065     }
3066
3067     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3068     color = getPixelColor(device, 160, 360);
3069     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3070     color = getPixelColor(device, 160, 120);
3071     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3072     color = getPixelColor(device, 480, 120);
3073     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3074     color = getPixelColor(device, 480, 360);
3075     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3076     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3077     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3078
3079     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3080     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3081
3082     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084
3085     hr = IDirect3DDevice9_BeginScene(device);
3086     if(SUCCEEDED(hr))
3087     {
3088         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3091         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3092
3093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3096         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3097
3098         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3102
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107         hr = IDirect3DDevice9_EndScene(device);
3108         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3109     }
3110
3111     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3112      * samples from the highest level in the texture(level 2)
3113      */
3114     color = getPixelColor(device, 160, 360);
3115     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3116     color = getPixelColor(device, 160, 120);
3117     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3118     color = getPixelColor(device, 480, 120);
3119     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3120     color = getPixelColor(device, 480, 360);
3121     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3122     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3123     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3124
3125     hr = IDirect3DDevice9_BeginScene(device);
3126     if(SUCCEEDED(hr))
3127     {
3128         DWORD ret;
3129
3130         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3131         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3134         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135         ret = IDirect3DTexture9_SetLOD(texture, 1);
3136         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139
3140         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3141         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3142         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3143         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3144         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3145         ret = IDirect3DTexture9_SetLOD(texture, 2);
3146         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3147         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3148         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3149
3150         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3151         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3152         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153         ret = IDirect3DTexture9_SetLOD(texture, 1);
3154         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3156         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3157
3158         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3159         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3160         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3162         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163         ret = IDirect3DTexture9_SetLOD(texture, 1);
3164         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3166         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167         hr = IDirect3DDevice9_EndScene(device);
3168     }
3169
3170     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3171      * samples from the highest level in the texture(level 2)
3172      */
3173     color = getPixelColor(device, 160, 360);
3174     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3175     color = getPixelColor(device, 160, 120);
3176     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3177     color = getPixelColor(device, 480, 120);
3178     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3179     color = getPixelColor(device, 480, 360);
3180     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3181     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3182     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3183
3184     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3185     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3186     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3188     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190     IDirect3DTexture9_Release(texture);
3191 }
3192
3193 static void release_buffer_test(IDirect3DDevice9 *device)
3194 {
3195     IDirect3DVertexBuffer9 *vb = NULL;
3196     IDirect3DIndexBuffer9 *ib = NULL;
3197     HRESULT hr;
3198     BYTE *data;
3199     LONG ref;
3200
3201     static const struct vertex quad[] = {
3202         {-1.0,      -1.0,       0.1,        0xffff0000},
3203         {-1.0,       1.0,       0.1,        0xffff0000},
3204         { 1.0,       1.0,       0.1,        0xffff0000},
3205
3206         {-1.0,      -1.0,       0.1,        0xff00ff00},
3207         {-1.0,       1.0,       0.1,        0xff00ff00},
3208         { 1.0,       1.0,       0.1,        0xff00ff00}
3209     };
3210     short indices[] = {3, 4, 5};
3211
3212     /* Index and vertex buffers should always be creatable */
3213     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3214                                               D3DPOOL_MANAGED, &vb, NULL);
3215     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3216     if(!vb) {
3217         skip("Failed to create a vertex buffer\n");
3218         return;
3219     }
3220     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3221     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3222     if(!ib) {
3223         skip("Failed to create an index buffer\n");
3224         return;
3225     }
3226
3227     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3228     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3229     memcpy(data, quad, sizeof(quad));
3230     hr = IDirect3DVertexBuffer9_Unlock(vb);
3231     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3232
3233     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3234     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3235     memcpy(data, indices, sizeof(indices));
3236     hr = IDirect3DIndexBuffer9_Unlock(ib);
3237     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3238
3239     hr = IDirect3DDevice9_SetIndices(device, ib);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3241     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3242     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3243     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3244     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3245
3246     /* Now destroy the bound index buffer and draw again */
3247     ref = IDirect3DIndexBuffer9_Release(ib);
3248     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3249
3250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3252
3253     hr = IDirect3DDevice9_BeginScene(device);
3254     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3255     if(SUCCEEDED(hr))
3256     {
3257         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3258          * making assumptions about the indices or vertices
3259          */
3260         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3261         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3262         hr = IDirect3DDevice9_EndScene(device);
3263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3264     }
3265
3266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3268
3269     hr = IDirect3DDevice9_SetIndices(device, NULL);
3270     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3271     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3273
3274     /* Index buffer was already destroyed as part of the test */
3275     IDirect3DVertexBuffer9_Release(vb);
3276 }
3277
3278 static void float_texture_test(IDirect3DDevice9 *device)
3279 {
3280     IDirect3D9 *d3d = NULL;
3281     HRESULT hr;
3282     IDirect3DTexture9 *texture = NULL;
3283     D3DLOCKED_RECT lr;
3284     float *data;
3285     DWORD color;
3286     float quad[] = {
3287         -1.0,      -1.0,       0.1,     0.0,    0.0,
3288         -1.0,       1.0,       0.1,     0.0,    1.0,
3289          1.0,      -1.0,       0.1,     1.0,    0.0,
3290          1.0,       1.0,       0.1,     1.0,    1.0,
3291     };
3292
3293     memset(&lr, 0, sizeof(lr));
3294     IDirect3DDevice9_GetDirect3D(device, &d3d);
3295     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3296                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3297         skip("D3DFMT_R32F textures not supported\n");
3298         goto out;
3299     }
3300
3301     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3302                                         D3DPOOL_MANAGED, &texture, NULL);
3303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3304     if(!texture) {
3305         skip("Failed to create R32F texture\n");
3306         goto out;
3307     }
3308
3309     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3310     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3311     data = lr.pBits;
3312     *data = 0.0;
3313     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3314     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3315
3316     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3317     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3318
3319     hr = IDirect3DDevice9_BeginScene(device);
3320     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3321     if(SUCCEEDED(hr))
3322     {
3323         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3324         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3325
3326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3327         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3328
3329         hr = IDirect3DDevice9_EndScene(device);
3330         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3331     }
3332     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3333     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3334
3335     color = getPixelColor(device, 240, 320);
3336     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3337
3338     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3339     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3340
3341 out:
3342     if(texture) IDirect3DTexture9_Release(texture);
3343     IDirect3D9_Release(d3d);
3344 }
3345
3346 static void g16r16_texture_test(IDirect3DDevice9 *device)
3347 {
3348     IDirect3D9 *d3d = NULL;
3349     HRESULT hr;
3350     IDirect3DTexture9 *texture = NULL;
3351     D3DLOCKED_RECT lr;
3352     DWORD *data;
3353     DWORD color;
3354     float quad[] = {
3355        -1.0,      -1.0,       0.1,     0.0,    0.0,
3356        -1.0,       1.0,       0.1,     0.0,    1.0,
3357         1.0,      -1.0,       0.1,     1.0,    0.0,
3358         1.0,       1.0,       0.1,     1.0,    1.0,
3359     };
3360
3361     memset(&lr, 0, sizeof(lr));
3362     IDirect3DDevice9_GetDirect3D(device, &d3d);
3363     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3364        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3365            skip("D3DFMT_G16R16 textures not supported\n");
3366            goto out;
3367     }
3368
3369     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3370                                         D3DPOOL_MANAGED, &texture, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3372     if(!texture) {
3373         skip("Failed to create D3DFMT_G16R16 texture\n");
3374         goto out;
3375     }
3376
3377     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379     data = lr.pBits;
3380     *data = 0x0f00f000;
3381     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3383
3384     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3386
3387     hr = IDirect3DDevice9_BeginScene(device);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389     if(SUCCEEDED(hr))
3390     {
3391         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3392         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3393
3394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3396
3397         hr = IDirect3DDevice9_EndScene(device);
3398         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3399     }
3400     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3401     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3402
3403     color = getPixelColor(device, 240, 320);
3404     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3405        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3406
3407     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3409
3410 out:
3411     if(texture) IDirect3DTexture9_Release(texture);
3412     IDirect3D9_Release(d3d);
3413 }
3414
3415 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3416 {
3417     HRESULT hr;
3418     IDirect3D9 *d3d;
3419     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3420     D3DCAPS9 caps;
3421     IDirect3DTexture9 *texture = NULL;
3422     IDirect3DVolumeTexture9 *volume = NULL;
3423     unsigned int x, y, z;
3424     D3DLOCKED_RECT lr;
3425     D3DLOCKED_BOX lb;
3426     DWORD color;
3427     UINT w, h;
3428     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3429     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3430                            0.0, 1.0, 0.0, 0.0,
3431                            0.0, 0.0, 1.0, 0.0,
3432                            0.0, 0.0, 0.0, 1.0};
3433     static const D3DVERTEXELEMENT9 decl_elements[] = {
3434         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3435         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3436         D3DDECL_END()
3437     };
3438     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3439         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3440         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3441         D3DDECL_END()
3442     };
3443     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3444         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3445         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3446         D3DDECL_END()
3447     };
3448     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3449                                                  0x00, 0xff, 0x00, 0x00,
3450                                                  0x00, 0x00, 0x00, 0x00,
3451                                                  0x00, 0x00, 0x00, 0x00};
3452
3453     memset(&lr, 0, sizeof(lr));
3454     memset(&lb, 0, sizeof(lb));
3455     IDirect3DDevice9_GetDirect3D(device, &d3d);
3456     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3457                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3458         fmt = D3DFMT_A16B16G16R16;
3459     }
3460     IDirect3D9_Release(d3d);
3461
3462     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3463     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3464     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3465     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3466     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3467     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3468     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3469     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3470     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3471     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3472     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3473     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3474     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3475     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3476     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3478     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3479     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3480     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3481     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3483     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3484     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3486
3487     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3489     w = min(1024, caps.MaxTextureWidth);
3490     h = min(1024, caps.MaxTextureHeight);
3491     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3492                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3493     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3494     if(!texture) {
3495         skip("Failed to create the test texture\n");
3496         return;
3497     }
3498
3499     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3500      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3501      * 1.0 in red and green for the x and y coords
3502      */
3503     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3504     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3505     for(y = 0; y < h; y++) {
3506         for(x = 0; x < w; x++) {
3507             double r_f = (double) y / (double) h;
3508             double g_f = (double) x / (double) w;
3509             if(fmt == D3DFMT_A16B16G16R16) {
3510                 unsigned short r, g;
3511                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3512                 r = (unsigned short) (r_f * 65536.0);
3513                 g = (unsigned short) (g_f * 65536.0);
3514                 dst[0] = r;
3515                 dst[1] = g;
3516                 dst[2] = 0;
3517                 dst[3] = 65535;
3518             } else {
3519                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3520                 unsigned char r = (unsigned char) (r_f * 255.0);
3521                 unsigned char g = (unsigned char) (g_f * 255.0);
3522                 dst[0] = 0;
3523                 dst[1] = g;
3524                 dst[2] = r;
3525                 dst[3] = 255;
3526             }
3527         }
3528     }
3529     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3530     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3531     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3532     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3533
3534     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3535     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3536     hr = IDirect3DDevice9_BeginScene(device);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3538     if(SUCCEEDED(hr))
3539     {
3540         float quad1[] = {
3541             -1.0,      -1.0,       0.1,     1.0,    1.0,
3542             -1.0,       0.0,       0.1,     1.0,    1.0,
3543              0.0,      -1.0,       0.1,     1.0,    1.0,
3544              0.0,       0.0,       0.1,     1.0,    1.0,
3545         };
3546         float quad2[] = {
3547             -1.0,       0.0,       0.1,     1.0,    1.0,
3548             -1.0,       1.0,       0.1,     1.0,    1.0,
3549              0.0,       0.0,       0.1,     1.0,    1.0,
3550              0.0,       1.0,       0.1,     1.0,    1.0,
3551         };
3552         float quad3[] = {
3553              0.0,       0.0,       0.1,     0.5,    0.5,
3554              0.0,       1.0,       0.1,     0.5,    0.5,
3555              1.0,       0.0,       0.1,     0.5,    0.5,
3556              1.0,       1.0,       0.1,     0.5,    0.5,
3557         };
3558         float quad4[] = {
3559              320,       480,       0.1,     1.0,    0.0,    1.0,
3560              320,       240,       0.1,     1.0,    0.0,    1.0,
3561              640,       480,       0.1,     1.0,    0.0,    1.0,
3562              640,       240,       0.1,     1.0,    0.0,    1.0,
3563         };
3564         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3565                           0.0, 0.0, 0.0, 0.0,
3566                           0.0, 0.0, 0.0, 0.0,
3567                           0.0, 0.0, 0.0, 0.0};
3568
3569         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3570         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3573         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3574
3575         /* What happens with transforms enabled? */
3576         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3577         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3579         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3580
3581         /* What happens if 4 coords are used, but only 2 given ?*/
3582         mat[8] = 1.0;
3583         mat[13] = 1.0;
3584         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3585         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3587         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3589         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3590
3591         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3592          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3593          * due to the coords in the vertices. (turns out red, indeed)
3594          */
3595         memset(mat, 0, sizeof(mat));
3596         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3597         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3599         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3600         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3603         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3604
3605         hr = IDirect3DDevice9_EndScene(device);
3606         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3607     }
3608     color = getPixelColor(device, 160, 360);
3609     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3610     color = getPixelColor(device, 160, 120);
3611     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3612     color = getPixelColor(device, 480, 120);
3613     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3614     color = getPixelColor(device, 480, 360);
3615     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3616     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3617     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3618
3619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3621
3622     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3624     hr = IDirect3DDevice9_BeginScene(device);
3625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3626     if(SUCCEEDED(hr))
3627     {
3628         float quad1[] = {
3629             -1.0,      -1.0,       0.1,     0.8,    0.2,
3630             -1.0,       0.0,       0.1,     0.8,    0.2,
3631              0.0,      -1.0,       0.1,     0.8,    0.2,
3632              0.0,       0.0,       0.1,     0.8,    0.2,
3633         };
3634         float quad2[] = {
3635             -1.0,       0.0,       0.1,     0.5,    1.0,
3636             -1.0,       1.0,       0.1,     0.5,    1.0,
3637              0.0,       0.0,       0.1,     0.5,    1.0,
3638              0.0,       1.0,       0.1,     0.5,    1.0,
3639         };
3640         float quad3[] = {
3641              0.0,       0.0,       0.1,     0.5,    1.0,
3642              0.0,       1.0,       0.1,     0.5,    1.0,
3643              1.0,       0.0,       0.1,     0.5,    1.0,
3644              1.0,       1.0,       0.1,     0.5,    1.0,
3645         };
3646         float quad4[] = {
3647              0.0,      -1.0,       0.1,     0.8,    0.2,
3648              0.0,       0.0,       0.1,     0.8,    0.2,
3649              1.0,      -1.0,       0.1,     0.8,    0.2,
3650              1.0,       0.0,       0.1,     0.8,    0.2,
3651         };
3652         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3653                           0.0, 0.0, 0.0, 0.0,
3654                           0.0, 1.0, 0.0, 0.0,
3655                           0.0, 0.0, 0.0, 0.0};
3656
3657         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3658          */
3659         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3661         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3662         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3663
3664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3665         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3666
3667         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3668          * it behaves like COUNT2 because normal textures require 2 coords
3669          */
3670         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3671         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3672         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3673         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3674
3675         /* Just to be sure, the same as quad2 above */
3676         memset(mat, 0, sizeof(mat));
3677         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3678         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3680         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3682         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3683
3684         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3685          * used? And what happens to the first?
3686          */
3687         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3688         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3690         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3691
3692         hr = IDirect3DDevice9_EndScene(device);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3694     }
3695     color = getPixelColor(device, 160, 360);
3696     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3697     color = getPixelColor(device, 160, 120);
3698     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3699     color = getPixelColor(device, 480, 120);
3700     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3701        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3702     color = getPixelColor(device, 480, 360);
3703     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3704        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3705     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3706     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3707
3708     IDirect3DTexture9_Release(texture);
3709
3710     /* Test projected textures, without any fancy matrices */
3711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3712     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3713     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3714     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3715     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3719
3720     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3721     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3722     for(x = 0; x < 4; x++) {
3723         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3724     }
3725     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3726     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3727     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3729
3730     hr = IDirect3DDevice9_BeginScene(device);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3732     if(SUCCEEDED(hr))
3733     {
3734         const float proj_quads[] = {
3735            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3736             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3737            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3738             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3739            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3740             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3741            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3742             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3743         };
3744
3745         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3746         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3748         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3749
3750         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3751         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3753         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3754
3755         hr = IDirect3DDevice9_EndScene(device);
3756         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3757     }
3758
3759     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3761     IDirect3DTexture9_Release(texture);
3762
3763     color = getPixelColor(device, 158, 118);
3764     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3765     color = getPixelColor(device, 162, 118);
3766     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3767     color = getPixelColor(device, 158, 122);
3768     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3769     color = getPixelColor(device, 162, 122);
3770     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3771
3772     color = getPixelColor(device, 158, 178);
3773     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3774     color = getPixelColor(device, 162, 178);
3775     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3776     color = getPixelColor(device, 158, 182);
3777     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3778     color = getPixelColor(device, 162, 182);
3779     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3780
3781     color = getPixelColor(device, 318, 118);
3782     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3783     color = getPixelColor(device, 322, 118);
3784     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3785     color = getPixelColor(device, 318, 122);
3786     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3787     color = getPixelColor(device, 322, 122);
3788     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3789
3790     color = getPixelColor(device, 318, 178);
3791     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3792     color = getPixelColor(device, 322, 178);
3793     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3794     color = getPixelColor(device, 318, 182);
3795     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3796     color = getPixelColor(device, 322, 182);
3797     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3798
3799     color = getPixelColor(device, 238, 298);
3800     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3801     color = getPixelColor(device, 242, 298);
3802     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 238, 302);
3804     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 242, 302);
3806     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3807
3808     color = getPixelColor(device, 238, 388);
3809     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3810     color = getPixelColor(device, 242, 388);
3811     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812     color = getPixelColor(device, 238, 392);
3813     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3814     color = getPixelColor(device, 242, 392);
3815     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3816
3817     color = getPixelColor(device, 478, 298);
3818     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3819     color = getPixelColor(device, 482, 298);
3820     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 478, 302);
3822     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3823     color = getPixelColor(device, 482, 302);
3824     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3825
3826     color = getPixelColor(device, 478, 388);
3827     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3828     color = getPixelColor(device, 482, 388);
3829     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3830     color = getPixelColor(device, 478, 392);
3831     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 482, 392);
3833     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3834
3835     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3836     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3837
3838     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3839     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3840     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3841      * Thus watch out if sampling from texels between 0 and 1.
3842      */
3843     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3844     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3845        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3846     if(!volume) {
3847         skip("Failed to create a volume texture\n");
3848         goto out;
3849     }
3850
3851     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3852     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3853     for(z = 0; z < 32; z++) {
3854         for(y = 0; y < 32; y++) {
3855             for(x = 0; x < 32; x++) {
3856                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3857                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3858                 float r_f = (float) x / 31.0;
3859                 float g_f = (float) y / 31.0;
3860                 float b_f = (float) z / 31.0;
3861
3862                 if(fmt == D3DFMT_A16B16G16R16) {
3863                     unsigned short *mem_s = mem;
3864                     mem_s[0]  = r_f * 65535.0;
3865                     mem_s[1]  = g_f * 65535.0;
3866                     mem_s[2]  = b_f * 65535.0;
3867                     mem_s[3]  = 65535;
3868                 } else {
3869                     unsigned char *mem_c = mem;
3870                     mem_c[0]  = b_f * 255.0;
3871                     mem_c[1]  = g_f * 255.0;
3872                     mem_c[2]  = r_f * 255.0;
3873                     mem_c[3]  = 255;
3874                 }
3875             }
3876         }
3877     }
3878     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3879     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3880
3881     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3882     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3883
3884     hr = IDirect3DDevice9_BeginScene(device);
3885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3886     if(SUCCEEDED(hr))
3887     {
3888         float quad1[] = {
3889             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3890             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3891              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3892              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3893         };
3894         float quad2[] = {
3895             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3896             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3897              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3898              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3899         };
3900         float quad3[] = {
3901              0.0,       0.0,       0.1,     0.0,    0.0,
3902              0.0,       1.0,       0.1,     0.0,    0.0,
3903              1.0,       0.0,       0.1,     0.0,    0.0,
3904              1.0,       1.0,       0.1,     0.0,    0.0
3905         };
3906         float quad4[] = {
3907              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3908              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3909              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3910              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3911         };
3912         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3913                          0.0, 0.0, 1.0, 0.0,
3914                          0.0, 1.0, 0.0, 0.0,
3915                          0.0, 0.0, 0.0, 1.0};
3916         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3917         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3918
3919         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3920          * values
3921          */
3922         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3924         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3927         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3928
3929         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3930          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3931          * otherwise the w will be missing(blue).
3932          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3933          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3934          */
3935         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3939
3940         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3941         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3942         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3946         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3948         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3949
3950         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3951          * disable. ATI extends it up to the amount of values needed for the volume texture
3952          */
3953         memset(mat, 0, sizeof(mat));
3954         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3956         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3957         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3958         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3959         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3962
3963         hr = IDirect3DDevice9_EndScene(device);
3964         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3965     }
3966
3967     color = getPixelColor(device, 160, 360);
3968     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3969     color = getPixelColor(device, 160, 120);
3970     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3971        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3972     color = getPixelColor(device, 480, 120);
3973     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3974     color = getPixelColor(device, 480, 360);
3975     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3976
3977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3979
3980     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3981     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3982     hr = IDirect3DDevice9_BeginScene(device);
3983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3984     if(SUCCEEDED(hr))
3985     {
3986         float quad1[] = {
3987             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3988             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3989              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3990              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3991         };
3992         float quad2[] = {
3993             -1.0,       0.0,       0.1,
3994             -1.0,       1.0,       0.1,
3995              0.0,       0.0,       0.1,
3996              0.0,       1.0,       0.1,
3997         };
3998         float quad3[] = {
3999              0.0,       0.0,       0.1,     1.0,
4000              0.0,       1.0,       0.1,     1.0,
4001              1.0,       0.0,       0.1,     1.0,
4002              1.0,       1.0,       0.1,     1.0
4003         };
4004         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4005                            0.0, 0.0, 0.0, 0.0,
4006                            0.0, 0.0, 0.0, 0.0,
4007                            0.0, 1.0, 0.0, 0.0};
4008         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4009                            1.0, 0.0, 0.0, 0.0,
4010                            0.0, 1.0, 0.0, 0.0,
4011                            0.0, 0.0, 1.0, 0.0};
4012         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4014
4015         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4016          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4017          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4018          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4019          * 4th *input* coordinate.
4020          */
4021         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4022         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4023         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4024         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4025         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4026         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4027
4028         /* None passed */
4029         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4030         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4031         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4032         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4033         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4034         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4035
4036         /* 4 used, 1 passed */
4037         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4038         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4039         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4040         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4041         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4042         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4043
4044         hr = IDirect3DDevice9_EndScene(device);
4045         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4046     }
4047     color = getPixelColor(device, 160, 360);
4048     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4049     color = getPixelColor(device, 160, 120);
4050     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4051     color = getPixelColor(device, 480, 120);
4052     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4053     /* Quad4: unused */
4054
4055     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4056     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4057
4058     IDirect3DVolumeTexture9_Release(volume);
4059
4060     out:
4061     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4062     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4063     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4064     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4065     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4066     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4067     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4068     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4069     IDirect3DVertexDeclaration9_Release(decl);
4070     IDirect3DVertexDeclaration9_Release(decl2);
4071     IDirect3DVertexDeclaration9_Release(decl3);
4072 }
4073
4074 static void texdepth_test(IDirect3DDevice9 *device)
4075 {
4076     IDirect3DPixelShader9 *shader;
4077     HRESULT hr;
4078     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4079     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4080     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4081     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4082     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4083     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4084     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4085     DWORD shader_code[] = {
4086         0xffff0104,                                                                 /* ps_1_4               */
4087         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4088         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4089         0x0000fffd,                                                                 /* phase                */
4090         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4091         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4092         0x0000ffff                                                                  /* end                  */
4093     };
4094     DWORD color;
4095     float vertex[] = {
4096        -1.0,   -1.0,    0.0,
4097         1.0,   -1.0,    1.0,
4098        -1.0,    1.0,    0.0,
4099         1.0,    1.0,    1.0
4100     };
4101
4102     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4103     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4104
4105     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4108     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4109     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4110     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4112     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4113     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4114     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4115
4116     /* Fill the depth buffer with a gradient */
4117     hr = IDirect3DDevice9_BeginScene(device);
4118     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4119     if(SUCCEEDED(hr))
4120     {
4121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4122         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4123         hr = IDirect3DDevice9_EndScene(device);
4124         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4125     }
4126
4127     /* Now perform the actual tests. Same geometry, but with the shader */
4128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4132     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4133     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4134
4135     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4136     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4137     hr = IDirect3DDevice9_BeginScene(device);
4138     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4139     if(SUCCEEDED(hr))
4140     {
4141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4142         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4143
4144         hr = IDirect3DDevice9_EndScene(device);
4145         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4146     }
4147
4148     color = getPixelColor(device, 158, 240);
4149     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4150     color = getPixelColor(device, 162, 240);
4151     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4152
4153     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4154     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4155
4156     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4157     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4158
4159     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4160     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4161     hr = IDirect3DDevice9_BeginScene(device);
4162     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4163     if(SUCCEEDED(hr))
4164     {
4165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4166         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4167
4168         hr = IDirect3DDevice9_EndScene(device);
4169         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4170     }
4171
4172     color = getPixelColor(device, 318, 240);
4173     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4174     color = getPixelColor(device, 322, 240);
4175     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4176
4177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4178     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4179
4180     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4181     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4182
4183     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4184     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4185     hr = IDirect3DDevice9_BeginScene(device);
4186     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4187     if(SUCCEEDED(hr))
4188     {
4189         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4190         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4191
4192         hr = IDirect3DDevice9_EndScene(device);
4193         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4194     }
4195
4196     color = getPixelColor(device, 1, 240);
4197     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4198
4199     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4200     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4201
4202     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4203     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4204
4205     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4206     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4207     hr = IDirect3DDevice9_BeginScene(device);
4208     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4209     if(SUCCEEDED(hr))
4210     {
4211         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4212         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4213
4214         hr = IDirect3DDevice9_EndScene(device);
4215         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4216     }
4217     color = getPixelColor(device, 318, 240);
4218     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4219     color = getPixelColor(device, 322, 240);
4220     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4221
4222     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4223     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4224
4225     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4226     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4227
4228     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4229     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4230     hr = IDirect3DDevice9_BeginScene(device);
4231     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4232     if(SUCCEEDED(hr))
4233     {
4234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4235         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4236
4237         hr = IDirect3DDevice9_EndScene(device);
4238         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4239     }
4240
4241     color = getPixelColor(device, 1, 240);
4242     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4243
4244     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4245     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4246
4247     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4248     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4249
4250     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4251     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4252     hr = IDirect3DDevice9_BeginScene(device);
4253     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4254     if(SUCCEEDED(hr))
4255     {
4256         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4257         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4258
4259         hr = IDirect3DDevice9_EndScene(device);
4260         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4261     }
4262
4263     color = getPixelColor(device, 638, 240);
4264     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4265
4266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4268
4269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4270     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4271
4272     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4273     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4274     hr = IDirect3DDevice9_BeginScene(device);
4275     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4276     if(SUCCEEDED(hr))
4277     {
4278         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4279         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4280
4281         hr = IDirect3DDevice9_EndScene(device);
4282         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4283     }
4284
4285     color = getPixelColor(device, 638, 240);
4286     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4287
4288     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4290
4291     /* Cleanup */
4292     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4293     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4294     IDirect3DPixelShader9_Release(shader);
4295
4296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4300 }
4301
4302 static void texkill_test(IDirect3DDevice9 *device)
4303 {
4304     IDirect3DPixelShader9 *shader;
4305     HRESULT hr;
4306     DWORD color;
4307
4308     const float vertex[] = {
4309     /*                          bottom  top    right    left */
4310         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4311          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4312         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4313          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4314     };
4315
4316     DWORD shader_code_11[] = {
4317     0xffff0101,                                                             /* ps_1_1                     */
4318     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4319     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4320     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4321     0x0000ffff                                                              /* end                        */
4322     };
4323     DWORD shader_code_20[] = {
4324     0xffff0200,                                                             /* ps_2_0                     */
4325     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4326     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4327     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4328     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4329     0x0000ffff                                                              /* end                        */
4330     };
4331
4332     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4333     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4334     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4335     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4336
4337     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4338     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4339     hr = IDirect3DDevice9_BeginScene(device);
4340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4341     if(SUCCEEDED(hr))
4342     {
4343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4346         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4347         hr = IDirect3DDevice9_EndScene(device);
4348         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4349     }
4350     color = getPixelColor(device, 63, 46);
4351     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4352     color = getPixelColor(device, 66, 46);
4353     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4354     color = getPixelColor(device, 63, 49);
4355     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4356     color = getPixelColor(device, 66, 49);
4357     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4358
4359     color = getPixelColor(device, 578, 46);
4360     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4361     color = getPixelColor(device, 575, 46);
4362     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4363     color = getPixelColor(device, 578, 49);
4364     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4365     color = getPixelColor(device, 575, 49);
4366     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4367
4368     color = getPixelColor(device, 63, 430);
4369     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4370     color = getPixelColor(device, 63, 433);
4371     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4372     color = getPixelColor(device, 66, 433);
4373     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4374     color = getPixelColor(device, 66, 430);
4375     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4376
4377     color = getPixelColor(device, 578, 430);
4378     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4379     color = getPixelColor(device, 578, 433);
4380     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4381     color = getPixelColor(device, 575, 433);
4382     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4383     color = getPixelColor(device, 575, 430);
4384     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4385
4386     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4387     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4388
4389     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4390     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4391     IDirect3DPixelShader9_Release(shader);
4392
4393     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4395     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4396     if(FAILED(hr)) {
4397         skip("Failed to create 2.0 test shader, most likely not supported\n");
4398         return;
4399     }
4400
4401     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4402     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4403     hr = IDirect3DDevice9_BeginScene(device);
4404     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4405     if(SUCCEEDED(hr))
4406     {
4407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4409         hr = IDirect3DDevice9_EndScene(device);
4410         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4411     }
4412
4413     color = getPixelColor(device, 63, 46);
4414     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4415     color = getPixelColor(device, 66, 46);
4416     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4417     color = getPixelColor(device, 63, 49);
4418     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4419     color = getPixelColor(device, 66, 49);
4420     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4421
4422     color = getPixelColor(device, 578, 46);
4423     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4424     color = getPixelColor(device, 575, 46);
4425     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4426     color = getPixelColor(device, 578, 49);
4427     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4428     color = getPixelColor(device, 575, 49);
4429     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4430
4431     color = getPixelColor(device, 63, 430);
4432     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4433     color = getPixelColor(device, 63, 433);
4434     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4435     color = getPixelColor(device, 66, 433);
4436     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4437     color = getPixelColor(device, 66, 430);
4438     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4439
4440     color = getPixelColor(device, 578, 430);
4441     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4442     color = getPixelColor(device, 578, 433);
4443     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4444     color = getPixelColor(device, 575, 433);
4445     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4446     color = getPixelColor(device, 575, 430);
4447     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4448
4449     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4450     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4451
4452     /* Cleanup */
4453     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4454     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4455     IDirect3DPixelShader9_Release(shader);
4456 }
4457
4458 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4459 {
4460     IDirect3D9 *d3d9;
4461     HRESULT hr;
4462     IDirect3DTexture9 *texture;
4463     IDirect3DPixelShader9 *shader;
4464     IDirect3DPixelShader9 *shader2;
4465     D3DLOCKED_RECT lr;
4466     DWORD color;
4467     DWORD shader_code[] = {
4468         0xffff0101,                             /* ps_1_1       */
4469         0x00000042, 0xb00f0000,                 /* tex t0       */
4470         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4471         0x0000ffff                              /* end          */
4472     };
4473     DWORD shader_code2[] = {
4474         0xffff0101,                             /* ps_1_1       */
4475         0x00000042, 0xb00f0000,                 /* tex t0       */
4476         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4477         0x0000ffff                              /* end          */
4478     };
4479
4480     float quad[] = {
4481        -1.0,   -1.0,   0.1,     0.5,    0.5,
4482         1.0,   -1.0,   0.1,     0.5,    0.5,
4483        -1.0,    1.0,   0.1,     0.5,    0.5,
4484         1.0,    1.0,   0.1,     0.5,    0.5,
4485     };
4486
4487     memset(&lr, 0, sizeof(lr));
4488     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4489     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4490                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4491     IDirect3D9_Release(d3d9);
4492     if(FAILED(hr)) {
4493         skip("No D3DFMT_X8L8V8U8 support\n");
4494         return;
4495     };
4496
4497     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4498     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4499
4500     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4501     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4502     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4503     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4504     *((DWORD *) lr.pBits) = 0x11ca3141;
4505     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4506     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4507
4508     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4509     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4510     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4511     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4512
4513     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4514     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4515     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4516     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4517     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4518     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4519
4520     hr = IDirect3DDevice9_BeginScene(device);
4521     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4522     if(SUCCEEDED(hr))
4523     {
4524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4525         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4526
4527         hr = IDirect3DDevice9_EndScene(device);
4528         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4529     }
4530     color = getPixelColor(device, 578, 430);
4531     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4532        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4533     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4534     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4535
4536     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4537     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4538     hr = IDirect3DDevice9_BeginScene(device);
4539     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4540     if(SUCCEEDED(hr))
4541     {
4542         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4543         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4544
4545         hr = IDirect3DDevice9_EndScene(device);
4546         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4547     }
4548     color = getPixelColor(device, 578, 430);
4549     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4550     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4551     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4552
4553     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4554     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4555     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4556     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4557     IDirect3DPixelShader9_Release(shader);
4558     IDirect3DPixelShader9_Release(shader2);
4559     IDirect3DTexture9_Release(texture);
4560 }
4561
4562 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4563 {
4564     HRESULT hr;
4565     IDirect3D9 *d3d;
4566     IDirect3DTexture9 *texture = NULL;
4567     IDirect3DSurface9 *surface;
4568     DWORD color;
4569     const RECT r1 = {256, 256, 512, 512};
4570     const RECT r2 = {512, 256, 768, 512};
4571     const RECT r3 = {256, 512, 512, 768};
4572     const RECT r4 = {512, 512, 768, 768};
4573     unsigned int x, y;
4574     D3DLOCKED_RECT lr;
4575     memset(&lr, 0, sizeof(lr));
4576
4577     IDirect3DDevice9_GetDirect3D(device, &d3d);
4578     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4579        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4580         skip("No autogenmipmap support\n");
4581         IDirect3D9_Release(d3d);
4582         return;
4583     }
4584     IDirect3D9_Release(d3d);
4585
4586     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4587     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4588
4589     /* Make the mipmap big, so that a smaller mipmap is used
4590      */
4591     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4592                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4593     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4594
4595     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4596     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4597     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4598     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4599     for(y = 0; y < 1024; y++) {
4600         for(x = 0; x < 1024; x++) {
4601             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4602             POINT pt;
4603
4604             pt.x = x;
4605             pt.y = y;
4606             if(PtInRect(&r1, pt)) {
4607                 *dst = 0xffff0000;
4608             } else if(PtInRect(&r2, pt)) {
4609                 *dst = 0xff00ff00;
4610             } else if(PtInRect(&r3, pt)) {
4611                 *dst = 0xff0000ff;
4612             } else if(PtInRect(&r4, pt)) {
4613                 *dst = 0xff000000;
4614             } else {
4615                 *dst = 0xffffffff;
4616             }
4617         }
4618     }
4619     hr = IDirect3DSurface9_UnlockRect(surface);
4620     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4621     IDirect3DSurface9_Release(surface);
4622
4623     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4624     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4625     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4626     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4627
4628     hr = IDirect3DDevice9_BeginScene(device);
4629     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4630     if(SUCCEEDED(hr)) {
4631         const float quad[] =  {
4632            -0.5,   -0.5,    0.1,    0.0,    0.0,
4633            -0.5,    0.5,    0.1,    0.0,    1.0,
4634             0.5,   -0.5,    0.1,    1.0,    0.0,
4635             0.5,    0.5,    0.1,    1.0,    1.0
4636         };
4637
4638         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4639         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4641         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4642         hr = IDirect3DDevice9_EndScene(device);
4643         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4644     }
4645     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4646     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4647     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4649     IDirect3DTexture9_Release(texture);
4650
4651     color = getPixelColor(device, 200, 200);
4652     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4653     color = getPixelColor(device, 280, 200);
4654     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4655     color = getPixelColor(device, 360, 200);
4656     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4657     color = getPixelColor(device, 440, 200);
4658     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4659     color = getPixelColor(device, 200, 270);
4660     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4661     color = getPixelColor(device, 280, 270);
4662     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4663     color = getPixelColor(device, 360, 270);
4664     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4665     color = getPixelColor(device, 440, 270);
4666     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4667     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4668     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4669 }
4670
4671 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4672 {
4673     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4674     IDirect3DVertexDeclaration9 *decl;
4675     HRESULT hr;
4676     DWORD color;
4677     DWORD shader_code_11[] =  {
4678         0xfffe0101,                                         /* vs_1_1           */
4679         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4680         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4681         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4682         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4683         0x0000ffff                                          /* end              */
4684     };
4685     DWORD shader_code_11_2[] =  {
4686         0xfffe0101,                                         /* vs_1_1           */
4687         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4688         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4689         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4690         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4691         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4692         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4693         0x0000ffff                                          /* end              */
4694     };
4695     DWORD shader_code_20[] =  {
4696         0xfffe0200,                                         /* vs_2_0           */
4697         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4698         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4699         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4700         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4701         0x0000ffff                                          /* end              */
4702     };
4703     DWORD shader_code_20_2[] =  {
4704         0xfffe0200,                                         /* vs_2_0           */
4705         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4706         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4707         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4708         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4709         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4710         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4711         0x0000ffff                                          /* end              */
4712     };
4713     static const D3DVERTEXELEMENT9 decl_elements[] = {
4714         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4715         D3DDECL_END()
4716     };
4717     float quad1[] = {
4718         -1.0,   -1.0,   0.1,
4719          0.0,   -1.0,   0.1,
4720         -1.0,    0.0,   0.1,
4721          0.0,    0.0,   0.1
4722     };
4723     float quad2[] = {
4724          0.0,   -1.0,   0.1,
4725          1.0,   -1.0,   0.1,
4726          0.0,    0.0,   0.1,
4727          1.0,    0.0,   0.1
4728     };
4729     float quad3[] = {
4730          0.0,    0.0,   0.1,
4731          1.0,    0.0,   0.1,
4732          0.0,    1.0,   0.1,
4733          1.0,    1.0,   0.1
4734     };
4735     float quad4[] = {
4736         -1.0,    0.0,   0.1,
4737          0.0,    0.0,   0.1,
4738         -1.0,    1.0,   0.1,
4739          0.0,    1.0,   0.1
4740     };
4741     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4742     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4743
4744     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4746
4747     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4748     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4749     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4750     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4751     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4752     if(FAILED(hr)) shader_20 = NULL;
4753     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4754     if(FAILED(hr)) shader_20_2 = NULL;
4755     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4756     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4757
4758     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4760     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4761     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4762     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4763     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4764
4765     hr = IDirect3DDevice9_BeginScene(device);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4767     if(SUCCEEDED(hr))
4768     {
4769         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4770         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4772         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4773
4774         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4775         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4777         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4778
4779         if(shader_20) {
4780             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4781             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4782             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4783             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4784         }
4785
4786         if(shader_20_2) {
4787             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4788             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4789             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4790             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791         }
4792
4793         hr = IDirect3DDevice9_EndScene(device);
4794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4795     }
4796
4797     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4798     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4799     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4800     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4801
4802     color = getPixelColor(device, 160, 360);
4803     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4804        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4805     color = getPixelColor(device, 480, 360);
4806     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4807        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4808     if(shader_20) {
4809         color = getPixelColor(device, 160, 120);
4810         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4811            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4812     }
4813     if(shader_20_2) {
4814         color = getPixelColor(device, 480, 120);
4815         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4816            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4817     }
4818     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4819     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4820
4821     IDirect3DVertexDeclaration9_Release(decl);
4822     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4823     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4824     IDirect3DVertexShader9_Release(shader_11_2);
4825     IDirect3DVertexShader9_Release(shader_11);
4826 }
4827
4828 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4829 {
4830     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4831     HRESULT hr;
4832     DWORD color;
4833     DWORD shader_code_11[] =  {
4834         0xffff0101,                                         /* ps_1_1           */
4835         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4836         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4837         0x0000ffff                                          /* end              */
4838     };
4839     DWORD shader_code_12[] =  {
4840         0xffff0102,                                         /* ps_1_2           */
4841         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4842         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4843         0x0000ffff                                          /* end              */
4844     };
4845     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4846      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4847      * During development of this test, 1.3 shaders were verified too
4848      */
4849     DWORD shader_code_14[] =  {
4850         0xffff0104,                                         /* ps_1_4           */
4851         /* Try to make one constant local. It gets clamped too, although the binary contains
4852          * the bigger numbers
4853          */
4854         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4855         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4856         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4857         0x0000ffff                                          /* end              */
4858     };
4859     DWORD shader_code_20[] =  {
4860         0xffff0200,                                         /* ps_2_0           */
4861         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4862         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4863         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4864         0x0000ffff                                          /* end              */
4865     };
4866     float quad1[] = {
4867         -1.0,   -1.0,   0.1,
4868          0.0,   -1.0,   0.1,
4869         -1.0,    0.0,   0.1,
4870          0.0,    0.0,   0.1
4871     };
4872     float quad2[] = {
4873          0.0,   -1.0,   0.1,
4874          1.0,   -1.0,   0.1,
4875          0.0,    0.0,   0.1,
4876          1.0,    0.0,   0.1
4877     };
4878     float quad3[] = {
4879          0.0,    0.0,   0.1,
4880          1.0,    0.0,   0.1,
4881          0.0,    1.0,   0.1,
4882          1.0,    1.0,   0.1
4883     };
4884     float quad4[] = {
4885         -1.0,    0.0,   0.1,
4886          0.0,    0.0,   0.1,
4887         -1.0,    1.0,   0.1,
4888          0.0,    1.0,   0.1
4889     };
4890     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4891     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4892
4893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4894     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4895
4896     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4897     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4898     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4899     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4900     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4901     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4902     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4903     if(FAILED(hr)) shader_20 = NULL;
4904
4905     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4906     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4907     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4908     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4910     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4911
4912     hr = IDirect3DDevice9_BeginScene(device);
4913     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4914     if(SUCCEEDED(hr))
4915     {
4916         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4917         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4919         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4920
4921         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4922         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4923         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4924         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4925
4926         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4927         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4928         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4929         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4930
4931         if(shader_20) {
4932             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4933             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4934             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4935             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4936         }
4937
4938         hr = IDirect3DDevice9_EndScene(device);
4939         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4940     }
4941     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4942     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4943
4944     color = getPixelColor(device, 160, 360);
4945     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4946        "quad 1 has color %08x, expected 0x00808000\n", color);
4947     color = getPixelColor(device, 480, 360);
4948     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4949        "quad 2 has color %08x, expected 0x00808000\n", color);
4950     color = getPixelColor(device, 480, 120);
4951     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4952        "quad 3 has color %08x, expected 0x00808000\n", color);
4953     if(shader_20) {
4954         color = getPixelColor(device, 160, 120);
4955         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4956            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4957     }
4958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4959     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4960
4961     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4962     IDirect3DPixelShader9_Release(shader_14);
4963     IDirect3DPixelShader9_Release(shader_12);
4964     IDirect3DPixelShader9_Release(shader_11);
4965 }
4966
4967 static void dp2add_ps_test(IDirect3DDevice9 *device)
4968 {
4969     IDirect3DPixelShader9 *shader_dp2add = NULL;
4970     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4971     HRESULT hr;
4972     DWORD color;
4973
4974     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4975      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4976      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4977      * r0 first.
4978      * The result here for the r,g,b components should be roughly 0.5:
4979      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4980     static const DWORD shader_code_dp2add[] =  {
4981         0xffff0200,                                                             /* ps_2_0                       */
4982         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4983
4984         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4985         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4986
4987         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4988         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4989         0x0000ffff                                                              /* end                          */
4990     };
4991
4992     /* Test the _sat modifier, too.  Result here should be:
4993      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4994      *      _SAT: ==> 1.0
4995      *   ADD: (1.0 + -0.5) = 0.5
4996      */
4997     static const DWORD shader_code_dp2add_sat[] =  {
4998         0xffff0200,                                                             /* ps_2_0                           */
4999         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5000
5001         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5002         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5003         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5004
5005         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5006         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5007         0x0000ffff                                                              /* end                              */
5008     };
5009
5010     const float quad[] = {
5011         -1.0,   -1.0,   0.1,
5012          1.0,   -1.0,   0.1,
5013         -1.0,    1.0,   0.1,
5014          1.0,    1.0,   0.1
5015     };
5016
5017
5018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5020
5021     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5022     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5023
5024     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5025     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5026
5027     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5028     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5029
5030     if (shader_dp2add) {
5031
5032         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5033         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5034
5035         hr = IDirect3DDevice9_BeginScene(device);
5036         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5037         if(SUCCEEDED(hr))
5038         {
5039             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5040             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5041
5042             hr = IDirect3DDevice9_EndScene(device);
5043             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5044         }
5045
5046         color = getPixelColor(device, 360, 240);
5047         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5048                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5049
5050         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5051         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5052
5053         IDirect3DPixelShader9_Release(shader_dp2add);
5054     } else {
5055         skip("dp2add shader creation failed\n");
5056     }
5057
5058     if (shader_dp2add_sat) {
5059
5060         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5061         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5062
5063         hr = IDirect3DDevice9_BeginScene(device);
5064         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5065         if(SUCCEEDED(hr))
5066         {
5067             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5068             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5069
5070             hr = IDirect3DDevice9_EndScene(device);
5071             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5072         }
5073
5074         color = getPixelColor(device, 360, 240);
5075         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5076                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5077
5078         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5080
5081         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5082     } else {
5083         skip("dp2add shader creation failed\n");
5084     }
5085
5086     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5087     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5088 }
5089
5090 static void cnd_test(IDirect3DDevice9 *device)
5091 {
5092     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5093     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5094     HRESULT hr;
5095     DWORD color;
5096     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5097      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5098      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5099      */
5100     DWORD shader_code_11[] =  {
5101         0xffff0101,                                                                 /* ps_1_1               */
5102         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5103         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5104         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5105         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5106         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5107         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5108         0x0000ffff                                                                  /* end                  */
5109     };
5110     DWORD shader_code_12[] =  {
5111         0xffff0102,                                                                 /* ps_1_2               */
5112         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5113         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5114         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5115         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5116         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5117         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5118         0x0000ffff                                                                  /* end                  */
5119     };
5120     DWORD shader_code_13[] =  {
5121         0xffff0103,                                                                 /* ps_1_3               */
5122         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5123         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5124         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5125         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5126         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5127         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5128         0x0000ffff                                                                  /* end                  */
5129     };
5130     DWORD shader_code_14[] =  {
5131         0xffff0104,                                                                 /* ps_1_3               */
5132         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5133         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5134         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5135         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5136         0x0000ffff                                                                  /* end                  */
5137     };
5138
5139     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5140      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5141      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5142      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5143      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5144      * good enough.
5145      *
5146      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5147      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5148      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5149      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5150      */
5151     DWORD shader_code_11_coissue[] =  {
5152         0xffff0101,                                                             /* ps_1_1                   */
5153         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5154         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5155         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5156         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5157         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5158         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5159         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5160         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5161         /* 0x40000000 = D3DSI_COISSUE */
5162         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5163         0x0000ffff                                                              /* end                      */
5164     };
5165     DWORD shader_code_12_coissue[] =  {
5166         0xffff0102,                                                             /* ps_1_2                   */
5167         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5168         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5169         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5170         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5171         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5172         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5173         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5174         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5175         /* 0x40000000 = D3DSI_COISSUE */
5176         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5177         0x0000ffff                                                              /* end                      */
5178     };
5179     DWORD shader_code_13_coissue[] =  {
5180         0xffff0103,                                                             /* ps_1_3                   */
5181         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5182         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5183         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5184         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5185         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5186         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5187         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5188         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5189         /* 0x40000000 = D3DSI_COISSUE */
5190         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5191         0x0000ffff                                                              /* end                      */
5192     };
5193     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5194      * compare against 0.5
5195      */
5196     DWORD shader_code_14_coissue[] =  {
5197         0xffff0104,                                                             /* ps_1_4                   */
5198         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5199         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5200         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5201         /* 0x40000000 = D3DSI_COISSUE */
5202         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5203         0x0000ffff                                                              /* end                      */
5204     };
5205     float quad1[] = {
5206         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5207          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5208         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5209          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5210     };
5211     float quad2[] = {
5212          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5213          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5214          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5215          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5216     };
5217     float quad3[] = {
5218          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5219          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5220          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5221          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5222     };
5223     float quad4[] = {
5224         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5225          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5226         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5227          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5228     };
5229     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5230     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5231     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5232     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5233
5234     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5235     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5236
5237     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5238     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5239     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5240     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5241     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5242     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5243     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5244     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5245     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5246     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5247     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5248     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5249     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5250     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5251     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5252     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5253
5254     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5255     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5256     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5257     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5258     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5259     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5260
5261     hr = IDirect3DDevice9_BeginScene(device);
5262     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5263     if(SUCCEEDED(hr))
5264     {
5265         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5266         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5267         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5268         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5269
5270         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5271         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5274
5275         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5276         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5277         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5278         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5279
5280         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5281         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5283         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5284
5285         hr = IDirect3DDevice9_EndScene(device);
5286         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5287     }
5288
5289     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5291
5292     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5293     color = getPixelColor(device, 158, 118);
5294     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5295     color = getPixelColor(device, 162, 118);
5296     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5297     color = getPixelColor(device, 158, 122);
5298     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5299     color = getPixelColor(device, 162, 122);
5300     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5301
5302     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5303     color = getPixelColor(device, 158, 358);
5304     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5305     color = getPixelColor(device, 162, 358);
5306     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5307         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5308     color = getPixelColor(device, 158, 362);
5309     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5310     color = getPixelColor(device, 162, 362);
5311     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5312         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5313
5314     /* 1.2 shader */
5315     color = getPixelColor(device, 478, 358);
5316     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5317     color = getPixelColor(device, 482, 358);
5318     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5319         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5320     color = getPixelColor(device, 478, 362);
5321     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5322     color = getPixelColor(device, 482, 362);
5323     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5324         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5325
5326     /* 1.3 shader */
5327     color = getPixelColor(device, 478, 118);
5328     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5329     color = getPixelColor(device, 482, 118);
5330     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5332     color = getPixelColor(device, 478, 122);
5333     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5334     color = getPixelColor(device, 482, 122);
5335     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5336         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5337
5338     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5339     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5340
5341     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5342     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5343     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5344     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5345     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5346     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5347
5348     hr = IDirect3DDevice9_BeginScene(device);
5349     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5350     if(SUCCEEDED(hr))
5351     {
5352         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5353         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5354         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5355         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5356
5357         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5358         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5360         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5361
5362         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5363         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5365         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5366
5367         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5368         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5369         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5370         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5371
5372         hr = IDirect3DDevice9_EndScene(device);
5373         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5374     }
5375
5376     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5377     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5378
5379     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5380      * that we swapped the values in c1 and c2 to make the other tests return some color
5381      */
5382     color = getPixelColor(device, 158, 118);
5383     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5384     color = getPixelColor(device, 162, 118);
5385     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5386     color = getPixelColor(device, 158, 122);
5387     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5388     color = getPixelColor(device, 162, 122);
5389     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5390
5391     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5392      * (The Win7 nvidia driver always selects c2)
5393      */
5394     color = getPixelColor(device, 158, 358);
5395     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5396         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5397     color = getPixelColor(device, 162, 358);
5398     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5399         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5400     color = getPixelColor(device, 158, 362);
5401     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5402         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5403     color = getPixelColor(device, 162, 362);
5404     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5405         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5406
5407     /* 1.2 shader */
5408     color = getPixelColor(device, 478, 358);
5409     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5410         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5411     color = getPixelColor(device, 482, 358);
5412     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5413         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5414     color = getPixelColor(device, 478, 362);
5415     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5416         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5417     color = getPixelColor(device, 482, 362);
5418     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5419         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5420
5421     /* 1.3 shader */
5422     color = getPixelColor(device, 478, 118);
5423     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5424         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5425     color = getPixelColor(device, 482, 118);
5426     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5427         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5428     color = getPixelColor(device, 478, 122);
5429     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5430         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5431     color = getPixelColor(device, 482, 122);
5432     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5433         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5434
5435     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5436     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5437
5438     IDirect3DPixelShader9_Release(shader_14_coissue);
5439     IDirect3DPixelShader9_Release(shader_13_coissue);
5440     IDirect3DPixelShader9_Release(shader_12_coissue);
5441     IDirect3DPixelShader9_Release(shader_11_coissue);
5442     IDirect3DPixelShader9_Release(shader_14);
5443     IDirect3DPixelShader9_Release(shader_13);
5444     IDirect3DPixelShader9_Release(shader_12);
5445     IDirect3DPixelShader9_Release(shader_11);
5446 }
5447
5448 static void nested_loop_test(IDirect3DDevice9 *device) {
5449     const DWORD shader_code[] = {
5450         0xffff0300,                                                             /* ps_3_0               */
5451         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5452         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5453         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5454         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5455         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5456         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5457         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5458         0x0000001d,                                                             /* endloop              */
5459         0x0000001d,                                                             /* endloop              */
5460         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5461         0x0000ffff                                                              /* end                  */
5462     };
5463     const DWORD vshader_code[] = {
5464         0xfffe0300,                                                             /* vs_3_0               */
5465         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5466         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5467         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5468         0x0000ffff                                                              /* end                  */
5469     };
5470     IDirect3DPixelShader9 *shader;
5471     IDirect3DVertexShader9 *vshader;
5472     HRESULT hr;
5473     DWORD color;
5474     const float quad[] = {
5475         -1.0,   -1.0,   0.1,
5476          1.0,   -1.0,   0.1,
5477         -1.0,    1.0,   0.1,
5478          1.0,    1.0,   0.1
5479     };
5480
5481     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5482     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5483     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5484     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5485     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5486     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5487     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5488     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5489     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5490     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5491     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5492     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5493
5494     hr = IDirect3DDevice9_BeginScene(device);
5495     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5496     if(SUCCEEDED(hr))
5497     {
5498         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5499         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5500         hr = IDirect3DDevice9_EndScene(device);
5501         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5502     }
5503
5504     color = getPixelColor(device, 360, 240);
5505     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5506        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5507
5508     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5509     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5510
5511     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5512     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5513     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5514     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5515     IDirect3DPixelShader9_Release(shader);
5516     IDirect3DVertexShader9_Release(vshader);
5517 }
5518
5519 struct varying_test_struct
5520 {
5521     const DWORD             *shader_code;
5522     IDirect3DPixelShader9   *shader;
5523     DWORD                   color, color_rhw;
5524     const char              *name;
5525     BOOL                    todo, todo_rhw;
5526 };
5527
5528 struct hugeVertex
5529 {
5530     float pos_x,        pos_y,      pos_z,      rhw;
5531     float weight_1,     weight_2,   weight_3,   weight_4;
5532     float index_1,      index_2,    index_3,    index_4;
5533     float normal_1,     normal_2,   normal_3,   normal_4;
5534     float fog_1,        fog_2,      fog_3,      fog_4;
5535     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5536     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5537     float binormal_1,   binormal_2, binormal_3, binormal_4;
5538     float depth_1,      depth_2,    depth_3,    depth_4;
5539     DWORD diffuse, specular;
5540 };
5541
5542 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5543     /* dcl_position: fails to compile */
5544     const DWORD blendweight_code[] = {
5545         0xffff0300,                             /* ps_3_0                   */
5546         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5547         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5548         0x0000ffff                              /* end                      */
5549     };
5550     const DWORD blendindices_code[] = {
5551         0xffff0300,                             /* ps_3_0                   */
5552         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5553         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5554         0x0000ffff                              /* end                      */
5555     };
5556     const DWORD normal_code[] = {
5557         0xffff0300,                             /* ps_3_0                   */
5558         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5559         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5560         0x0000ffff                              /* end                      */
5561     };
5562     /* psize: fails? */
5563     const DWORD texcoord0_code[] = {
5564         0xffff0300,                             /* ps_3_0                   */
5565         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5566         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5567         0x0000ffff                              /* end                      */
5568     };
5569     const DWORD tangent_code[] = {
5570         0xffff0300,                             /* ps_3_0                   */
5571         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5572         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5573         0x0000ffff                              /* end                      */
5574     };
5575     const DWORD binormal_code[] = {
5576         0xffff0300,                             /* ps_3_0                   */
5577         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5578         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5579         0x0000ffff                              /* end                      */
5580     };
5581     /* tessfactor: fails */
5582     /* positiont: fails */
5583     const DWORD color_code[] = {
5584         0xffff0300,                             /* ps_3_0                   */
5585         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5586         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5587         0x0000ffff                              /* end                      */
5588     };
5589     const DWORD fog_code[] = {
5590         0xffff0300,                             /* ps_3_0                   */
5591         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5592         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5593         0x0000ffff                              /* end                      */
5594     };
5595     const DWORD depth_code[] = {
5596         0xffff0300,                             /* ps_3_0                   */
5597         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5598         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5599         0x0000ffff                              /* end                      */
5600     };
5601     const DWORD specular_code[] = {
5602         0xffff0300,                             /* ps_3_0                   */
5603         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5604         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5605         0x0000ffff                              /* end                      */
5606     };
5607     /* sample: fails */
5608
5609     struct varying_test_struct tests[] = {
5610        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5611        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5612        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5613        /* Why does dx not forward the texcoord? */
5614        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5615        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5616        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5617        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5618        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5619        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5620        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5621     };
5622     /* Declare a monster vertex type :-) */
5623     static const D3DVERTEXELEMENT9 decl_elements[] = {
5624         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5625         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5626         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5627         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5628         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5629         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5630         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5631         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5632         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5633         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5634         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5635         D3DDECL_END()
5636     };
5637     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5638         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5639         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5640         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5641         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5642         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5643         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5644         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5645         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5646         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5647         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5648         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5649         D3DDECL_END()
5650     };
5651     struct hugeVertex data[4] = {
5652         {
5653             -1.0,   -1.0,   0.1,    1.0,
5654              0.1,    0.1,   0.1,    0.1,
5655              0.2,    0.2,   0.2,    0.2,
5656              0.3,    0.3,   0.3,    0.3,
5657              0.4,    0.4,   0.4,    0.4,
5658              0.50,   0.55,  0.55,   0.55,
5659              0.6,    0.6,   0.6,    0.7,
5660              0.7,    0.7,   0.7,    0.6,
5661              0.8,    0.8,   0.8,    0.8,
5662              0xe6e6e6e6, /* 0.9 * 256 */
5663              0x224488ff  /* Nothing special */
5664         },
5665         {
5666              1.0,   -1.0,   0.1,    1.0,
5667              0.1,    0.1,   0.1,    0.1,
5668              0.2,    0.2,   0.2,    0.2,
5669              0.3,    0.3,   0.3,    0.3,
5670              0.4,    0.4,   0.4,    0.4,
5671              0.50,   0.55,  0.55,   0.55,
5672              0.6,    0.6,   0.6,    0.7,
5673              0.7,    0.7,   0.7,    0.6,
5674              0.8,    0.8,   0.8,    0.8,
5675              0xe6e6e6e6, /* 0.9 * 256 */
5676              0x224488ff /* Nothing special */
5677         },
5678         {
5679             -1.0,    1.0,   0.1,    1.0,
5680              0.1,    0.1,   0.1,    0.1,
5681              0.2,    0.2,   0.2,    0.2,
5682              0.3,    0.3,   0.3,    0.3,
5683              0.4,    0.4,   0.4,    0.4,
5684              0.50,   0.55,  0.55,   0.55,
5685              0.6,    0.6,   0.6,    0.7,
5686              0.7,    0.7,   0.7,    0.6,
5687              0.8,    0.8,   0.8,    0.8,
5688              0xe6e6e6e6, /* 0.9 * 256 */
5689              0x224488ff /* Nothing special */
5690         },
5691         {
5692              1.0,    1.0,   0.1,    1.0,
5693              0.1,    0.1,   0.1,    0.1,
5694              0.2,    0.2,   0.2,    0.2,
5695              0.3,    0.3,   0.3,    0.3,
5696              0.4,    0.4,   0.4,    0.4,
5697              0.50,   0.55,  0.55,   0.55,
5698              0.6,    0.6,   0.6,    0.7,
5699              0.7,    0.7,   0.7,    0.6,
5700              0.8,    0.8,   0.8,    0.8,
5701              0xe6e6e6e6, /* 0.9 * 256 */
5702              0x224488ff /* Nothing special */
5703         },
5704     };
5705     struct hugeVertex data2[4];
5706     IDirect3DVertexDeclaration9 *decl;
5707     IDirect3DVertexDeclaration9 *decl2;
5708     HRESULT hr;
5709     unsigned int i;
5710     DWORD color, r, g, b, r_e, g_e, b_e;
5711     BOOL drawok;
5712
5713     memcpy(data2, data, sizeof(data2));
5714     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5715     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5716     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5717     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5718
5719     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5720     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5721     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5722     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5723     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5724     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5725
5726     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5727     {
5728         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5729         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5730            tests[i].name, hr);
5731     }
5732
5733     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5734     {
5735         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5736         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5737
5738         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5739         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5740
5741         hr = IDirect3DDevice9_BeginScene(device);
5742         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5743         drawok = FALSE;
5744         if(SUCCEEDED(hr))
5745         {
5746             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5747             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5748             drawok = SUCCEEDED(hr);
5749             hr = IDirect3DDevice9_EndScene(device);
5750             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5751         }
5752
5753         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5754          * the failure and do not check the color if it failed
5755          */
5756         if(!drawok) {
5757             continue;
5758         }
5759
5760         color = getPixelColor(device, 360, 240);
5761         r = color & 0x00ff0000 >> 16;
5762         g = color & 0x0000ff00 >>  8;
5763         b = color & 0x000000ff;
5764         r_e = tests[i].color & 0x00ff0000 >> 16;
5765         g_e = tests[i].color & 0x0000ff00 >>  8;
5766         b_e = tests[i].color & 0x000000ff;
5767
5768         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5769         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5770
5771         if(tests[i].todo) {
5772             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5773                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5774                          tests[i].name, color, tests[i].color);
5775         } else {
5776             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5777                "Test %s returned color 0x%08x, expected 0x%08x\n",
5778                tests[i].name, color, tests[i].color);
5779         }
5780     }
5781
5782     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5783     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5784     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5785     {
5786         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5787         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5788
5789         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5790         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5791
5792         hr = IDirect3DDevice9_BeginScene(device);
5793         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5794         if(SUCCEEDED(hr))
5795         {
5796             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5797             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5798             hr = IDirect3DDevice9_EndScene(device);
5799             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5800         }
5801
5802         color = getPixelColor(device, 360, 240);
5803         r = color & 0x00ff0000 >> 16;
5804         g = color & 0x0000ff00 >>  8;
5805         b = color & 0x000000ff;
5806         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5807         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5808         b_e = tests[i].color_rhw & 0x000000ff;
5809
5810         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5811         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5812
5813         if(tests[i].todo_rhw) {
5814             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5815              * pipeline
5816              */
5817             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5818                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5819                          tests[i].name, color, tests[i].color_rhw);
5820         } else {
5821             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5822                "Test %s returned color 0x%08x, expected 0x%08x\n",
5823                tests[i].name, color, tests[i].color_rhw);
5824         }
5825     }
5826
5827     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5828     {
5829         IDirect3DPixelShader9_Release(tests[i].shader);
5830     }
5831
5832     IDirect3DVertexDeclaration9_Release(decl2);
5833     IDirect3DVertexDeclaration9_Release(decl);
5834 }
5835
5836 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5837     static const DWORD ps_code[] = {
5838     0xffff0300,                                                             /* ps_3_0                       */
5839     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5840     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5841     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5842     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5843     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5844     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5845     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5846     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5847     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5848
5849     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5850     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5851     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5852     0x0000001d,                                                             /* endloop                      */
5853     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5854     0x0000ffff                                                              /* end                          */
5855     };
5856     static const DWORD vs_1_code[] = {
5857     0xfffe0101,                                                             /* vs_1_1                       */
5858     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5859     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5860     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5861     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5862     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5863     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5864     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5865     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5866     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5867     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5868     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5869     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5870     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5871     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5872     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5873     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5874     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5875     0x0000ffff
5876     };
5877     DWORD vs_2_code[] = {
5878     0xfffe0200,                                                             /* vs_2_0                       */
5879     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5880     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5881     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5882     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5883     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5884     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5885     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5886     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5887     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5888     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5889     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5890     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5891     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5892     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5893     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5894     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5895     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5896     0x0000ffff                                                              /* end                          */
5897     };
5898     /* TODO: Define normal, tangent, blendweight and depth here */
5899     static const DWORD vs_3_code[] = {
5900     0xfffe0300,                                                             /* vs_3_0                       */
5901     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5902     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5903     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5904     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5905     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5906     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5907     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5908     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5909     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5910     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5911     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5912     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5913     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5914     0x0000ffff                                                              /* end                          */
5915     };
5916     float quad1[] =  {
5917         -1.0,   -1.0,   0.1,
5918          0.0,   -1.0,   0.1,
5919         -1.0,    0.0,   0.1,
5920          0.0,    0.0,   0.1
5921     };
5922     float quad2[] =  {
5923          0.0,   -1.0,   0.1,
5924          1.0,   -1.0,   0.1,
5925          0.0,    0.0,   0.1,
5926          1.0,    0.0,   0.1
5927     };
5928     float quad3[] =  {
5929         -1.0,    0.0,   0.1,
5930          0.0,    0.0,   0.1,
5931         -1.0,    1.0,   0.1,
5932          0.0,    1.0,   0.1
5933     };
5934
5935     HRESULT hr;
5936     DWORD color;
5937     IDirect3DPixelShader9 *pixelshader = NULL;
5938     IDirect3DVertexShader9 *vs_1_shader = NULL;
5939     IDirect3DVertexShader9 *vs_2_shader = NULL;
5940     IDirect3DVertexShader9 *vs_3_shader = NULL;
5941
5942     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5943     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5944
5945     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5946     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5947     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5948     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5949     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5950     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5951     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5952     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5953     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5954     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5955     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5956
5957     hr = IDirect3DDevice9_BeginScene(device);
5958     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5959     if(SUCCEEDED(hr))
5960     {
5961         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5962         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5963         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5964         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5965
5966         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5967         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5969         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5970
5971         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5972         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5973         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5974         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5975
5976         hr = IDirect3DDevice9_EndScene(device);
5977         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5978     }
5979
5980     color = getPixelColor(device, 160, 120);
5981     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5982        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5983     /* Accept two ways of oFog handling:
5984      *
5985      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5986      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5987      *
5988      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5989      *    This happens with software vertex processing and on Intel cards
5990      *
5991      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5992      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5993      */
5994     color = getPixelColor(device, 160, 360);
5995     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5996        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5997        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5998     color = getPixelColor(device, 480, 360);
5999     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
6000        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
6001        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
6002
6003     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6004     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6005
6006     /* cleanup */
6007     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6008     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6009     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6010     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6011     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
6012     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
6013     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
6014     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
6015 }
6016
6017 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
6018     static const DWORD vs_code[] = {
6019     0xfffe0300,                                                             /* vs_3_0                       */
6020     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6021     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
6022     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
6023     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
6024     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
6025     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
6026     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
6027     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
6028     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
6029     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
6030     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
6031     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
6032     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
6033
6034     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
6035     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
6036     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
6037     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
6038     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
6039     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
6040     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
6041     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
6042     0x0000ffff                                                              /* end                          */
6043     };
6044     static const DWORD ps_1_code[] = {
6045     0xffff0104,                                                             /* ps_1_4                       */
6046     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6047     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
6048     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
6049     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
6050     0x0000ffff                                                              /* end                          */
6051     };
6052     static const DWORD ps_2_code[] = {
6053     0xffff0200,                                                             /* ps_2_0                       */
6054     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
6055     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
6056     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
6057
6058     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6059     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
6060     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6061     0x0000ffff                                                              /* end                          */
6062     };
6063     static const DWORD ps_3_code[] = {
6064     0xffff0300,                                                             /* ps_3_0                       */
6065     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
6066     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
6067     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
6068
6069     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6070     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
6071     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
6072     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6073     0x0000ffff                                                              /* end                          */
6074     };
6075
6076     float quad1[] =  {
6077         -1.0,   -1.0,   0.1,
6078          0.0,   -1.0,   0.1,
6079         -1.0,    0.0,   0.1,
6080          0.0,    0.0,   0.1
6081     };
6082     float quad2[] =  {
6083          0.0,   -1.0,   0.1,
6084          1.0,   -1.0,   0.1,
6085          0.0,    0.0,   0.1,
6086          1.0,    0.0,   0.1
6087     };
6088     float quad3[] =  {
6089         -1.0,    0.0,   0.1,
6090          0.0,    0.0,   0.1,
6091         -1.0,    1.0,   0.1,
6092          0.0,    1.0,   0.1
6093     };
6094     float quad4[] =  {
6095          0.0,    0.0,   0.1,
6096          1.0,    0.0,   0.1,
6097          0.0,    1.0,   0.1,
6098          1.0,    1.0,   0.1
6099     };
6100
6101     HRESULT hr;
6102     DWORD color;
6103     IDirect3DVertexShader9 *vertexshader = NULL;
6104     IDirect3DPixelShader9 *ps_1_shader = NULL;
6105     IDirect3DPixelShader9 *ps_2_shader = NULL;
6106     IDirect3DPixelShader9 *ps_3_shader = NULL;
6107     IDirect3DTexture9 *texture = NULL;
6108     D3DLOCKED_RECT lr;
6109     unsigned int x, y;
6110
6111     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6112     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6113
6114     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6115     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6116     if(FAILED(hr)) {
6117         skip("D3DFMT_A16B16G16R16 textures not supported\n");
6118         return;
6119     }
6120     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6121     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6122     for(y = 0; y < 512; y++) {
6123         for(x = 0; x < 512; x++) {
6124             double r_f = (double) x / (double) 512;
6125             double g_f = (double) y / (double) 512;
6126             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6127             unsigned short r = (unsigned short) (r_f * 65535.0);
6128             unsigned short g = (unsigned short) (g_f * 65535.0);
6129             dst[0] = r;
6130             dst[1] = g;
6131             dst[2] = 0;
6132             dst[3] = 65535;
6133         }
6134     }
6135     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6136     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6137
6138     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6139     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6140     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6141     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6142     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6143     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6144     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6145     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6146     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6147     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6148     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6149
6150     hr = IDirect3DDevice9_BeginScene(device);
6151     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6152     if(SUCCEEDED(hr))
6153     {
6154         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6155         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6157         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6158
6159         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6160         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6162         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6163
6164         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6165         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6166         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6167         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6168
6169         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6170         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6171         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6172         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6173         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6174         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6175         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6176         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6177         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6178         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6179         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6180         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6181         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6182         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6183
6184         hr = IDirect3DDevice9_EndScene(device);
6185         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6186     }
6187
6188     color = getPixelColor(device, 160, 120);
6189     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6190        (color & 0x0000ff00) == 0x0000ff00 &&
6191        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6192        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6193     color = getPixelColor(device, 160, 360);
6194     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6195        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6196        (color & 0x000000ff) == 0x00000000,
6197        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6198     color = getPixelColor(device, 480, 360);
6199     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6200        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6201        (color & 0x000000ff) == 0x00000000,
6202        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6203     color = getPixelColor(device, 480, 160);
6204     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6205        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6206        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6207        (color & 0x000000ff) == 0x00000000),
6208        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6209
6210     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6211     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6212
6213     /* cleanup */
6214     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6215     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6216     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6217     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6218     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6219     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6220     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6221     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6222     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6223     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6224     if(texture) IDirect3DTexture9_Release(texture);
6225 }
6226
6227 static void test_compare_instructions(IDirect3DDevice9 *device)
6228 {
6229     DWORD shader_sge_vec_code[] = {
6230         0xfffe0101,                                         /* vs_1_1                   */
6231         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6232         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6233         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6234         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6235         0x0000ffff                                          /* end                      */
6236     };
6237     DWORD shader_slt_vec_code[] = {
6238         0xfffe0101,                                         /* vs_1_1                   */
6239         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6240         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6241         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6242         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6243         0x0000ffff                                          /* end                      */
6244     };
6245     DWORD shader_sge_scalar_code[] = {
6246         0xfffe0101,                                         /* vs_1_1                   */
6247         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6248         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6249         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6250         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6251         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6252         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6253         0x0000ffff                                          /* end                      */
6254     };
6255     DWORD shader_slt_scalar_code[] = {
6256         0xfffe0101,                                         /* vs_1_1                   */
6257         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6258         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6259         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6260         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6261         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6262         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6263         0x0000ffff                                          /* end                      */
6264     };
6265     IDirect3DVertexShader9 *shader_sge_vec;
6266     IDirect3DVertexShader9 *shader_slt_vec;
6267     IDirect3DVertexShader9 *shader_sge_scalar;
6268     IDirect3DVertexShader9 *shader_slt_scalar;
6269     HRESULT hr, color;
6270     float quad1[] =  {
6271         -1.0,   -1.0,   0.1,
6272          0.0,   -1.0,   0.1,
6273         -1.0,    0.0,   0.1,
6274          0.0,    0.0,   0.1
6275     };
6276     float quad2[] =  {
6277          0.0,   -1.0,   0.1,
6278          1.0,   -1.0,   0.1,
6279          0.0,    0.0,   0.1,
6280          1.0,    0.0,   0.1
6281     };
6282     float quad3[] =  {
6283         -1.0,    0.0,   0.1,
6284          0.0,    0.0,   0.1,
6285         -1.0,    1.0,   0.1,
6286          0.0,    1.0,   0.1
6287     };
6288     float quad4[] =  {
6289          0.0,    0.0,   0.1,
6290          1.0,    0.0,   0.1,
6291          0.0,    1.0,   0.1,
6292          1.0,    1.0,   0.1
6293     };
6294     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6295     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6296
6297     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6298     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6299
6300     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6302     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6304     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6305     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6306     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6307     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6308     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6309     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6310     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6311     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6312     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6313     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6314
6315     hr = IDirect3DDevice9_BeginScene(device);
6316     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6317     if(SUCCEEDED(hr))
6318     {
6319         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6320         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6323
6324         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6325         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6327         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6328
6329         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6330         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6331         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6332         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6333
6334         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6335         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6336
6337         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6338         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6339         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6340         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6341
6342         hr = IDirect3DDevice9_EndScene(device);
6343         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6344     }
6345
6346     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6347     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6348
6349     color = getPixelColor(device, 160, 360);
6350     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6351     color = getPixelColor(device, 480, 360);
6352     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6353     color = getPixelColor(device, 160, 120);
6354     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6355     color = getPixelColor(device, 480, 160);
6356     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6357
6358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6359     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6360
6361     IDirect3DVertexShader9_Release(shader_sge_vec);
6362     IDirect3DVertexShader9_Release(shader_slt_vec);
6363     IDirect3DVertexShader9_Release(shader_sge_scalar);
6364     IDirect3DVertexShader9_Release(shader_slt_scalar);
6365 }
6366
6367 static void test_vshader_input(IDirect3DDevice9 *device)
6368 {
6369     DWORD swapped_shader_code_3[] = {
6370         0xfffe0300,                                         /* vs_3_0               */
6371         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6372         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6373         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6374         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6375         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6376         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6377         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6378         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6379         0x0000ffff                                          /* end                  */
6380     };
6381     DWORD swapped_shader_code_1[] = {
6382         0xfffe0101,                                         /* vs_1_1               */
6383         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6384         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6385         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6386         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6387         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6388         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6389         0x0000ffff                                          /* end                  */
6390     };
6391     DWORD swapped_shader_code_2[] = {
6392         0xfffe0200,                                         /* vs_2_0               */
6393         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6394         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6395         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6396         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6397         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6398         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6399         0x0000ffff                                          /* end                  */
6400     };
6401     DWORD texcoord_color_shader_code_3[] = {
6402         0xfffe0300,                                         /* vs_3_0               */
6403         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6404         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6405         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6406         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6407         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6408         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6409         0x0000ffff                                          /* end                  */
6410     };
6411     DWORD texcoord_color_shader_code_2[] = {
6412         0xfffe0200,                                         /* vs_2_0               */
6413         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6414         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6415         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6416         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6417         0x0000ffff                                          /* end                  */
6418     };
6419     DWORD texcoord_color_shader_code_1[] = {
6420         0xfffe0101,                                         /* vs_1_1               */
6421         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6422         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6423         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6424         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6425         0x0000ffff                                          /* end                  */
6426     };
6427     DWORD color_color_shader_code_3[] = {
6428         0xfffe0300,                                         /* vs_3_0               */
6429         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6430         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6431         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6432         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6433         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6434         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6435         0x0000ffff                                          /* end                  */
6436     };
6437     DWORD color_color_shader_code_2[] = {
6438         0xfffe0200,                                         /* vs_2_0               */
6439         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6440         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6441         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6442         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6443         0x0000ffff                                          /* end                  */
6444     };
6445     DWORD color_color_shader_code_1[] = {
6446         0xfffe0101,                                         /* vs_1_1               */
6447         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6448         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6449         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6450         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6451         0x0000ffff                                          /* end                  */
6452     };
6453     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6454     HRESULT hr;
6455     DWORD color;
6456     float quad1[] =  {
6457         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6458          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6459         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6460          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6461     };
6462     float quad2[] =  {
6463          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6464          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6465          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6466          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6467     };
6468     float quad3[] =  {
6469         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6470          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6471         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6472          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6473     };
6474     float quad4[] =  {
6475          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6476          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6477          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6478          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6479     };
6480     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6481         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6482         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6483         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6484         D3DDECL_END()
6485     };
6486     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6487         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6488         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6489         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6490         D3DDECL_END()
6491     };
6492     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6493         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6494         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6495         D3DDECL_END()
6496     };
6497     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6498         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6499         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6500         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6501         D3DDECL_END()
6502     };
6503     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6504         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6505         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6506         D3DDECL_END()
6507     };
6508     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6509         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6510         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6511         D3DDECL_END()
6512     };
6513     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6514         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6515         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6516         D3DDECL_END()
6517     };
6518     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6519         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6520         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6521         D3DDECL_END()
6522     };
6523     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6524     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6525     unsigned int i;
6526     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6527     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6528
6529     struct vertex quad1_color[] =  {
6530        {-1.0,   -1.0,   0.1,    0x00ff8040},
6531        { 0.0,   -1.0,   0.1,    0x00ff8040},
6532        {-1.0,    0.0,   0.1,    0x00ff8040},
6533        { 0.0,    0.0,   0.1,    0x00ff8040}
6534     };
6535     struct vertex quad2_color[] =  {
6536        { 0.0,   -1.0,   0.1,    0x00ff8040},
6537        { 1.0,   -1.0,   0.1,    0x00ff8040},
6538        { 0.0,    0.0,   0.1,    0x00ff8040},
6539        { 1.0,    0.0,   0.1,    0x00ff8040}
6540     };
6541     struct vertex quad3_color[] =  {
6542        {-1.0,    0.0,   0.1,    0x00ff8040},
6543        { 0.0,    0.0,   0.1,    0x00ff8040},
6544        {-1.0,    1.0,   0.1,    0x00ff8040},
6545        { 0.0,    1.0,   0.1,    0x00ff8040}
6546     };
6547     float quad4_color[] =  {
6548          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6549          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6550          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6551          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6552     };
6553
6554     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6555     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6556     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6557     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6558     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6559     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6560     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6561     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6562
6563     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6564     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6565     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6566     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6567     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6568     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6569     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6570     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6571
6572     for(i = 1; i <= 3; i++) {
6573         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6574         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6575         if(i == 3) {
6576             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6577             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6578         } else if(i == 2){
6579             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6580             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6581         } else if(i == 1) {
6582             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6583             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6584         }
6585
6586         hr = IDirect3DDevice9_BeginScene(device);
6587         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6588         if(SUCCEEDED(hr))
6589         {
6590             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6591             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6592
6593             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6594             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6595             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6596             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6597
6598             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6599             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6600             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6601             if(i == 3 || i == 2) {
6602                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6603             } else if(i == 1) {
6604                 /* Succeeds or fails, depending on SW or HW vertex processing */
6605                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6606             }
6607
6608             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6609             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6610             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6611             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6612
6613             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6614             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6615             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6616             if(i == 3 || i == 2) {
6617                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6618             } else if(i == 1) {
6619                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6620             }
6621
6622             hr = IDirect3DDevice9_EndScene(device);
6623             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6624         }
6625
6626         if(i == 3 || i == 2) {
6627             color = getPixelColor(device, 160, 360);
6628             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6629                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6630
6631             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6632             color = getPixelColor(device, 480, 360);
6633             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6634                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6635             color = getPixelColor(device, 160, 120);
6636             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6637             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6638                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6639
6640             color = getPixelColor(device, 480, 160);
6641             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6642         } else if(i == 1) {
6643             color = getPixelColor(device, 160, 360);
6644             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6645                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6646             color = getPixelColor(device, 480, 360);
6647             /* Accept the clear color as well in this case, since SW VP returns an error */
6648             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6649             color = getPixelColor(device, 160, 120);
6650             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6651                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6652             color = getPixelColor(device, 480, 160);
6653             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6654         }
6655
6656         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6657         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6658
6659         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6660         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6661
6662         /* Now find out if the whole streams are re-read, or just the last active value for the
6663          * vertices is used.
6664          */
6665         hr = IDirect3DDevice9_BeginScene(device);
6666         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6667         if(SUCCEEDED(hr))
6668         {
6669             float quad1_modified[] =  {
6670                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6671                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6672                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6673                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6674             };
6675             float quad2_modified[] =  {
6676                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6677                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6678                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6679                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6680             };
6681
6682             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6683             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6684
6685             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6686             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6687             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6688             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6689
6690             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6691             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6692             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6693             if(i == 3 || i == 2) {
6694                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6695             } else if(i == 1) {
6696                 /* Succeeds or fails, depending on SW or HW vertex processing */
6697                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6698             }
6699
6700             hr = IDirect3DDevice9_EndScene(device);
6701             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6702         }
6703
6704         color = getPixelColor(device, 480, 350);
6705         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6706          * as well.
6707          *
6708          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6709          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6710          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6711          * refrast's result.
6712          *
6713          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6714          */
6715         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6716            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6717
6718         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6719         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6720
6721         IDirect3DDevice9_SetVertexShader(device, NULL);
6722         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6723
6724         IDirect3DVertexShader9_Release(swapped_shader);
6725     }
6726
6727     for(i = 1; i <= 3; i++) {
6728         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6729         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6730         if(i == 3) {
6731             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6732             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6733             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6734             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6735         } else if(i == 2){
6736             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6737             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6738             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6739             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6740         } else if(i == 1) {
6741             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6742             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6743             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6744             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6745         }
6746
6747         hr = IDirect3DDevice9_BeginScene(device);
6748         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6749         if(SUCCEEDED(hr))
6750         {
6751             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6752             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6753             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6754             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6755             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6756             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6757
6758             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6759             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6760
6761             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6762             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6763             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6764             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6765             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6766             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6767
6768             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6769             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6770             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6771             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6772             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6773             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6774
6775             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6776             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6777             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6778             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6779
6780             hr = IDirect3DDevice9_EndScene(device);
6781             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6782         }
6783         IDirect3DDevice9_SetVertexShader(device, NULL);
6784         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6785
6786         color = getPixelColor(device, 160, 360);
6787         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6788            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6789         color = getPixelColor(device, 480, 360);
6790         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6791            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6792         color = getPixelColor(device, 160, 120);
6793         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6794            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6795         color = getPixelColor(device, 480, 160);
6796         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6797            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6798
6799         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6800         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6801
6802         IDirect3DVertexShader9_Release(texcoord_color_shader);
6803         IDirect3DVertexShader9_Release(color_color_shader);
6804     }
6805
6806     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6807     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6808     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6809     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6810
6811     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6812     IDirect3DVertexDeclaration9_Release(decl_color_color);
6813     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6814     IDirect3DVertexDeclaration9_Release(decl_color_float);
6815 }
6816
6817 static void srgbtexture_test(IDirect3DDevice9 *device)
6818 {
6819     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6820      * texture stage state to render a quad using that texture.  The resulting
6821      * color components should be 0x36 (~ 0.21), per this formula:
6822      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6823      * This is true where srgb_color > 0.04045.
6824      */
6825     IDirect3D9 *d3d = NULL;
6826     HRESULT hr;
6827     LPDIRECT3DTEXTURE9 texture = NULL;
6828     LPDIRECT3DSURFACE9 surface = NULL;
6829     D3DLOCKED_RECT lr;
6830     DWORD color;
6831     float quad[] = {
6832         -1.0,       1.0,       0.0,     0.0,    0.0,
6833          1.0,       1.0,       0.0,     1.0,    0.0,
6834         -1.0,      -1.0,       0.0,     0.0,    1.0,
6835          1.0,      -1.0,       0.0,     1.0,    1.0,
6836     };
6837
6838
6839     memset(&lr, 0, sizeof(lr));
6840     IDirect3DDevice9_GetDirect3D(device, &d3d);
6841     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6842                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6843                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6844         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6845         goto out;
6846     }
6847
6848     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6849                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6850                                         &texture, NULL);
6851     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6852     if(!texture) {
6853         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6854         goto out;
6855     }
6856     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6857     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6858
6859     fill_surface(surface, 0xff7f7f7f);
6860     IDirect3DSurface9_Release(surface);
6861
6862     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6863     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6864     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6865     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6866
6867     hr = IDirect3DDevice9_BeginScene(device);
6868     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6869     if(SUCCEEDED(hr))
6870     {
6871         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6872         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6873
6874         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6875         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6876
6877
6878         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6879         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6880
6881         hr = IDirect3DDevice9_EndScene(device);
6882         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6883     }
6884
6885     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6886     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6887     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6888     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6889
6890     color = getPixelColor(device, 320, 240);
6891     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6892
6893     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6894     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6895
6896 out:
6897     if(texture) IDirect3DTexture9_Release(texture);
6898     IDirect3D9_Release(d3d);
6899 }
6900
6901 static void shademode_test(IDirect3DDevice9 *device)
6902 {
6903     /* Render a quad and try all of the different fixed function shading models. */
6904     HRESULT hr;
6905     DWORD color0, color1;
6906     DWORD color0_gouraud = 0, color1_gouraud = 0;
6907     DWORD shademode = D3DSHADE_FLAT;
6908     DWORD primtype = D3DPT_TRIANGLESTRIP;
6909     LPVOID data = NULL;
6910     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6911     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6912     UINT i, j;
6913     struct vertex quad_strip[] =
6914     {
6915         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6916         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6917         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6918         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6919     };
6920     struct vertex quad_list[] =
6921     {
6922         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6923         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6924         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6925
6926         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6927         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6928         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6929     };
6930
6931     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6932                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6933     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6934     if (FAILED(hr)) goto bail;
6935
6936     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6937                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6938     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6939     if (FAILED(hr)) goto bail;
6940
6941     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6942     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6943
6944     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6945     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6946
6947     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6948     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6949     memcpy(data, quad_strip, sizeof(quad_strip));
6950     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6951     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6952
6953     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6954     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6955     memcpy(data, quad_list, sizeof(quad_list));
6956     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6957     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6958
6959     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6960      * the color fixups we have to do for FLAT shading will be dependent on that. */
6961     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6962     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6963
6964     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6965     for (j=0; j<2; j++) {
6966
6967         /* Inner loop just changes the D3DRS_SHADEMODE */
6968         for (i=0; i<3; i++) {
6969             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6970             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6971
6972             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6973             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6974
6975             hr = IDirect3DDevice9_BeginScene(device);
6976             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6977             if(SUCCEEDED(hr))
6978             {
6979                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6980                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6981
6982                 hr = IDirect3DDevice9_EndScene(device);
6983                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6984             }
6985
6986             /* Sample two spots from the output */
6987             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6988             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6989             switch(shademode) {
6990                 case D3DSHADE_FLAT:
6991                     /* Should take the color of the first vertex of each triangle */
6992                     if (0)
6993                     {
6994                         /* This test depends on EXT_provoking_vertex being
6995                          * available. This extension is currently (20090810)
6996                          * not common enough to let the test fail if it isn't
6997                          * present. */
6998                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6999                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7000                     }
7001                     shademode = D3DSHADE_GOURAUD;
7002                     break;
7003                 case D3DSHADE_GOURAUD:
7004                     /* Should be an interpolated blend */
7005
7006                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7007                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7008                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7009                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7010
7011                     color0_gouraud = color0;
7012                     color1_gouraud = color1;
7013
7014                     shademode = D3DSHADE_PHONG;
7015                     break;
7016                 case D3DSHADE_PHONG:
7017                     /* Should be the same as GOURAUD, since no hardware implements this */
7018                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7019                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7020                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7021                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7022
7023                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7024                             color0_gouraud, color0);
7025                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7026                             color1_gouraud, color1);
7027                     break;
7028             }
7029         }
7030
7031         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7032         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7033
7034         /* Now, do it all over again with a TRIANGLELIST */
7035         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7036         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7037         primtype = D3DPT_TRIANGLELIST;
7038         shademode = D3DSHADE_FLAT;
7039     }
7040
7041 bail:
7042     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7043     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7044     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7045     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7046
7047     if (vb_strip)
7048         IDirect3DVertexBuffer9_Release(vb_strip);
7049     if (vb_list)
7050         IDirect3DVertexBuffer9_Release(vb_list);
7051 }
7052
7053 static void alpha_test(IDirect3DDevice9 *device)
7054 {
7055     HRESULT hr;
7056     IDirect3DTexture9 *offscreenTexture;
7057     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7058     DWORD color;
7059
7060     struct vertex quad1[] =
7061     {
7062         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7063         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7064         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7065         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7066     };
7067     struct vertex quad2[] =
7068     {
7069         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7070         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7071         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7072         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7073     };
7074     static const float composite_quad[][5] = {
7075         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7076         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7077         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7078         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7079     };
7080
7081     /* Clear the render target with alpha = 0.5 */
7082     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7083     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7084
7085     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7086     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7087
7088     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7089     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7090     if(!backbuffer) {
7091         goto out;
7092     }
7093
7094     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7095     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7096     if(!offscreen) {
7097         goto out;
7098     }
7099
7100     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7101     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7102
7103     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7104     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7105     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7106     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7107     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7108     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7109     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7110     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7112     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7113
7114     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7115     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7116     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7117
7118         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7119         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7120         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7121         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7122         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7124         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7125
7126         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7127         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7128         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7129         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7130         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7131         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7132
7133         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7134          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7135          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7136         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7137         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7138         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7139         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7140
7141         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7142         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7143         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7144         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7145         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7146         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7147
7148         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7149         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7150         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7151         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7152         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7153         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7154
7155         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7156         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7157
7158         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7159          * Disable alpha blending for the final composition
7160          */
7161         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7162         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7163         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7164         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7165
7166         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7167         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7168         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7169         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7170         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7171         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7172
7173         hr = IDirect3DDevice9_EndScene(device);
7174         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7175     }
7176
7177     color = getPixelColor(device, 160, 360);
7178     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7179        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7180
7181     color = getPixelColor(device, 160, 120);
7182     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7183        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7184
7185     color = getPixelColor(device, 480, 360);
7186     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7187        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7188
7189     color = getPixelColor(device, 480, 120);
7190     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7191        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7192
7193     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7194
7195     out:
7196     /* restore things */
7197     if(backbuffer) {
7198         IDirect3DSurface9_Release(backbuffer);
7199     }
7200     if(offscreenTexture) {
7201         IDirect3DTexture9_Release(offscreenTexture);
7202     }
7203     if(offscreen) {
7204         IDirect3DSurface9_Release(offscreen);
7205     }
7206 }
7207
7208 struct vertex_shortcolor {
7209     float x, y, z;
7210     unsigned short r, g, b, a;
7211 };
7212 struct vertex_floatcolor {
7213     float x, y, z;
7214     float r, g, b, a;
7215 };
7216
7217 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7218 {
7219     HRESULT hr;
7220     BOOL s_ok, ub_ok, f_ok;
7221     DWORD color, size, i;
7222     void *data;
7223     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7224         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7225         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7226         D3DDECL_END()
7227     };
7228     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7229         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7230         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7231         D3DDECL_END()
7232     };
7233     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7234         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7235         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7236         D3DDECL_END()
7237     };
7238     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7239         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7240         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7241         D3DDECL_END()
7242     };
7243     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7244         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7245         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7246         D3DDECL_END()
7247     };
7248     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7249         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7250         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7251         D3DDECL_END()
7252     };
7253     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7254         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7255         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7256         D3DDECL_END()
7257     };
7258     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7259     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7260     IDirect3DVertexBuffer9 *vb, *vb2;
7261     struct vertex quad1[] =                             /* D3DCOLOR */
7262     {
7263         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7264         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7265         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7266         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7267     };
7268     struct vertex quad2[] =                             /* UBYTE4N */
7269     {
7270         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7271         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7272         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7273         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7274     };
7275     struct vertex_shortcolor quad3[] =                  /* short */
7276     {
7277         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7278         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7279         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7280         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7281     };
7282     struct vertex_floatcolor quad4[] =
7283     {
7284         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7285         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7286         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7287         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7288     };
7289     DWORD colors[] = {
7290         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7291         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7292         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7293         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7294         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7295         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7296         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7297         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7298         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7299         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7300         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7301         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7302         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7303         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7304         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7305         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7306     };
7307     float quads[] = {
7308         -1.0,   -1.0,     0.1,
7309         -1.0,    0.0,     0.1,
7310          0.0,   -1.0,     0.1,
7311          0.0,    0.0,     0.1,
7312
7313          0.0,   -1.0,     0.1,
7314          0.0,    0.0,     0.1,
7315          1.0,   -1.0,     0.1,
7316          1.0,    0.0,     0.1,
7317
7318          0.0,    0.0,     0.1,
7319          0.0,    1.0,     0.1,
7320          1.0,    0.0,     0.1,
7321          1.0,    1.0,     0.1,
7322
7323         -1.0,    0.0,     0.1,
7324         -1.0,    1.0,     0.1,
7325          0.0,    0.0,     0.1,
7326          0.0,    1.0,     0.1
7327     };
7328     struct tvertex quad_transformed[] = {
7329        {  90,    110,     0.1,      2.0,        0x00ffff00},
7330        { 570,    110,     0.1,      2.0,        0x00ffff00},
7331        {  90,    300,     0.1,      2.0,        0x00ffff00},
7332        { 570,    300,     0.1,      2.0,        0x00ffff00}
7333     };
7334     D3DCAPS9 caps;
7335
7336     memset(&caps, 0, sizeof(caps));
7337     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7338     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7339
7340     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7341     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7342
7343     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7344     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7345     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7346     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7347     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7348     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7349     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7350         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7351         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7352         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7353         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7354     } else {
7355         trace("D3DDTCAPS_UBYTE4N not supported\n");
7356         dcl_ubyte_2 = NULL;
7357         dcl_ubyte = NULL;
7358     }
7359     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7360     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7361     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7362     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7363
7364     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7365     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7366                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7367     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7368
7369     hr = IDirect3DDevice9_BeginScene(device);
7370     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7371     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7372     if(SUCCEEDED(hr)) {
7373         if(dcl_color) {
7374             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7375             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7376             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7377             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7378         }
7379
7380         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7381          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7382          * using software vertex processing. Doh!
7383          */
7384         if(dcl_ubyte) {
7385             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7386             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7387             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7388             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7389             ub_ok = SUCCEEDED(hr);
7390         }
7391
7392         if(dcl_short) {
7393             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7394             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7395             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7396             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7397             s_ok = SUCCEEDED(hr);
7398         }
7399
7400         if(dcl_float) {
7401             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7402             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7403             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7404             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7405             f_ok = SUCCEEDED(hr);
7406         }
7407
7408         hr = IDirect3DDevice9_EndScene(device);
7409         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7410     }
7411
7412     if(dcl_short) {
7413         color = getPixelColor(device, 480, 360);
7414         ok(color == 0x000000ff || !s_ok,
7415            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7416     }
7417     if(dcl_ubyte) {
7418         color = getPixelColor(device, 160, 120);
7419         ok(color == 0x0000ffff || !ub_ok,
7420            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7421     }
7422     if(dcl_color) {
7423         color = getPixelColor(device, 160, 360);
7424         ok(color == 0x00ffff00,
7425            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7426     }
7427     if(dcl_float) {
7428         color = getPixelColor(device, 480, 120);
7429         ok(color == 0x00ff0000 || !f_ok,
7430            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7431     }
7432     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7433
7434     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7435      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7436      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7437      * whether the immediate mode code works
7438      */
7439     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7440     hr = IDirect3DDevice9_BeginScene(device);
7441     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7442     if(SUCCEEDED(hr)) {
7443         if(dcl_color) {
7444             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7445             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7446             memcpy(data, quad1, sizeof(quad1));
7447             hr = IDirect3DVertexBuffer9_Unlock(vb);
7448             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7449             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7450             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7451             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7452             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7453             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7454             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7455         }
7456
7457         if(dcl_ubyte) {
7458             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7459             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7460             memcpy(data, quad2, sizeof(quad2));
7461             hr = IDirect3DVertexBuffer9_Unlock(vb);
7462             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7463             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7464             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7465             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7466             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7467             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7468             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7469                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7470             ub_ok = SUCCEEDED(hr);
7471         }
7472
7473         if(dcl_short) {
7474             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7475             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7476             memcpy(data, quad3, sizeof(quad3));
7477             hr = IDirect3DVertexBuffer9_Unlock(vb);
7478             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7479             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7480             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7481             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7482             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7483             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7484             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7485                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7486             s_ok = SUCCEEDED(hr);
7487         }
7488
7489         if(dcl_float) {
7490             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7491             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7492             memcpy(data, quad4, sizeof(quad4));
7493             hr = IDirect3DVertexBuffer9_Unlock(vb);
7494             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7495             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7496             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7497             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7498             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7499             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7500             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7501                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7502             f_ok = SUCCEEDED(hr);
7503         }
7504
7505         hr = IDirect3DDevice9_EndScene(device);
7506         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7507     }
7508
7509     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7510     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7511     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7512     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7513
7514     if(dcl_short) {
7515         color = getPixelColor(device, 480, 360);
7516         ok(color == 0x000000ff || !s_ok,
7517            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7518     }
7519     if(dcl_ubyte) {
7520         color = getPixelColor(device, 160, 120);
7521         ok(color == 0x0000ffff || !ub_ok,
7522            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7523     }
7524     if(dcl_color) {
7525         color = getPixelColor(device, 160, 360);
7526         ok(color == 0x00ffff00,
7527            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7528     }
7529     if(dcl_float) {
7530         color = getPixelColor(device, 480, 120);
7531         ok(color == 0x00ff0000 || !f_ok,
7532            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7533     }
7534     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7535
7536     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7537     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7538
7539     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7540     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7541     memcpy(data, quad_transformed, sizeof(quad_transformed));
7542     hr = IDirect3DVertexBuffer9_Unlock(vb);
7543     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7544
7545     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7546     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7547
7548     hr = IDirect3DDevice9_BeginScene(device);
7549     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7550     if(SUCCEEDED(hr)) {
7551         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7552         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7553         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7554         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7555
7556         hr = IDirect3DDevice9_EndScene(device);
7557         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7558     }
7559
7560     color = getPixelColor(device, 88, 108);
7561     ok(color == 0x000000ff,
7562        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7563     color = getPixelColor(device, 92, 108);
7564     ok(color == 0x000000ff,
7565        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7566     color = getPixelColor(device, 88, 112);
7567     ok(color == 0x000000ff,
7568        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7569     color = getPixelColor(device, 92, 112);
7570     ok(color == 0x00ffff00,
7571        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7572
7573     color = getPixelColor(device, 568, 108);
7574     ok(color == 0x000000ff,
7575        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7576     color = getPixelColor(device, 572, 108);
7577     ok(color == 0x000000ff,
7578        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7579     color = getPixelColor(device, 568, 112);
7580     ok(color == 0x00ffff00,
7581        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7582     color = getPixelColor(device, 572, 112);
7583     ok(color == 0x000000ff,
7584        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7585
7586     color = getPixelColor(device, 88, 298);
7587     ok(color == 0x000000ff,
7588        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7589     color = getPixelColor(device, 92, 298);
7590     ok(color == 0x00ffff00,
7591        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7592     color = getPixelColor(device, 88, 302);
7593     ok(color == 0x000000ff,
7594        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7595     color = getPixelColor(device, 92, 302);
7596     ok(color == 0x000000ff,
7597        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7598
7599     color = getPixelColor(device, 568, 298);
7600     ok(color == 0x00ffff00,
7601        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7602     color = getPixelColor(device, 572, 298);
7603     ok(color == 0x000000ff,
7604        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7605     color = getPixelColor(device, 568, 302);
7606     ok(color == 0x000000ff,
7607        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7608     color = getPixelColor(device, 572, 302);
7609     ok(color == 0x000000ff,
7610        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7611
7612     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7613
7614     /* This test is pointless without those two declarations: */
7615     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7616         skip("color-ubyte switching test declarations aren't supported\n");
7617         goto out;
7618     }
7619
7620     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7621     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7622     memcpy(data, quads, sizeof(quads));
7623     hr = IDirect3DVertexBuffer9_Unlock(vb);
7624     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7625     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7626                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7627     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7628     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7629     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7630     memcpy(data, colors, sizeof(colors));
7631     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7632     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7633
7634     for(i = 0; i < 2; i++) {
7635         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7636         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7637
7638         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7639         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7640         if(i == 0) {
7641             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7642         } else {
7643             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7644         }
7645         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7646
7647         hr = IDirect3DDevice9_BeginScene(device);
7648         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7649         ub_ok = FALSE;
7650         if(SUCCEEDED(hr)) {
7651             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7652             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7653             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7654             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7655                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7656             ub_ok = SUCCEEDED(hr);
7657
7658             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7659             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7660             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7661             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7662
7663             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7664             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7665             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7666             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7667                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7668             ub_ok = (SUCCEEDED(hr) && ub_ok);
7669
7670             hr = IDirect3DDevice9_EndScene(device);
7671             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7672         }
7673
7674         if(i == 0) {
7675             color = getPixelColor(device, 480, 360);
7676             ok(color == 0x00ff0000,
7677                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7678             color = getPixelColor(device, 160, 120);
7679             ok(color == 0x00ffffff,
7680                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7681             color = getPixelColor(device, 160, 360);
7682             ok(color == 0x000000ff || !ub_ok,
7683                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7684             color = getPixelColor(device, 480, 120);
7685             ok(color == 0x000000ff || !ub_ok,
7686                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7687         } else {
7688             color = getPixelColor(device, 480, 360);
7689             ok(color == 0x000000ff,
7690                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7691             color = getPixelColor(device, 160, 120);
7692             ok(color == 0x00ffffff,
7693                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7694             color = getPixelColor(device, 160, 360);
7695             ok(color == 0x00ff0000 || !ub_ok,
7696                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7697             color = getPixelColor(device, 480, 120);
7698             ok(color == 0x00ff0000 || !ub_ok,
7699                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7700         }
7701         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7702     }
7703
7704     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7705     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7706     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7707     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7708     IDirect3DVertexBuffer9_Release(vb2);
7709
7710     out:
7711     IDirect3DVertexBuffer9_Release(vb);
7712     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7713     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7714     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7715     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7716     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7717     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7718     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7719 }
7720
7721 struct vertex_float16color {
7722     float x, y, z;
7723     DWORD c1, c2;
7724 };
7725
7726 static void test_vshader_float16(IDirect3DDevice9 *device)
7727 {
7728     HRESULT hr;
7729     DWORD color;
7730     void *data;
7731     static const D3DVERTEXELEMENT9 decl_elements[] = {
7732         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7733         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7734         D3DDECL_END()
7735     };
7736     IDirect3DVertexDeclaration9 *vdecl = NULL;
7737     IDirect3DVertexBuffer9 *buffer = NULL;
7738     IDirect3DVertexShader9 *shader;
7739     DWORD shader_code[] = {
7740         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7741         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7742         0x90e40001, 0x0000ffff
7743     };
7744     struct vertex_float16color quad[] = {
7745         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7746         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7747         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7748         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7749
7750         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7751         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7752         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7753         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7754
7755         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7756         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7757         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7758         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7759
7760         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7761         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7762         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7763         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7764     };
7765
7766     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7767     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7768
7769     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7770     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7771     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7772     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7773     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7774     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7775
7776     hr = IDirect3DDevice9_BeginScene(device);
7777     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7778     if(SUCCEEDED(hr)) {
7779         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7780         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7781         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7782         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7783         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7784         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7786         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7787         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7788         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7789
7790         hr = IDirect3DDevice9_EndScene(device);
7791         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7792     }
7793     color = getPixelColor(device, 480, 360);
7794     ok(color == 0x00ff0000,
7795        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7796     color = getPixelColor(device, 160, 120);
7797     ok(color == 0x00000000,
7798        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7799     color = getPixelColor(device, 160, 360);
7800     ok(color == 0x0000ff00,
7801        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7802     color = getPixelColor(device, 480, 120);
7803     ok(color == 0x000000ff,
7804        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7805     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7806
7807     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7808     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7809
7810     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7811                                              D3DPOOL_MANAGED, &buffer, NULL);
7812     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7813     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7814     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7815     memcpy(data, quad, sizeof(quad));
7816     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7817     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7818     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7819     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7820
7821     hr = IDirect3DDevice9_BeginScene(device);
7822     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7823     if(SUCCEEDED(hr)) {
7824             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7825             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7826             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7827             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7828             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7829             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7830             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7831             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7832
7833             hr = IDirect3DDevice9_EndScene(device);
7834             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7835     }
7836
7837     color = getPixelColor(device, 480, 360);
7838     ok(color == 0x00ff0000,
7839        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7840     color = getPixelColor(device, 160, 120);
7841     ok(color == 0x00000000,
7842        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7843     color = getPixelColor(device, 160, 360);
7844     ok(color == 0x0000ff00,
7845        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7846     color = getPixelColor(device, 480, 120);
7847     ok(color == 0x000000ff,
7848        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7849     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7850
7851     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7852     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7853     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7854     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7855     IDirect3DDevice9_SetVertexShader(device, NULL);
7856     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7857
7858     IDirect3DVertexDeclaration9_Release(vdecl);
7859     IDirect3DVertexShader9_Release(shader);
7860     IDirect3DVertexBuffer9_Release(buffer);
7861 }
7862
7863 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7864 {
7865     D3DCAPS9 caps;
7866     IDirect3DTexture9 *texture;
7867     HRESULT hr;
7868     D3DLOCKED_RECT rect;
7869     unsigned int x, y;
7870     DWORD *dst, color;
7871     const float quad[] = {
7872         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7873          1.0,   -1.0,   0.1,    1.2,   -0.2,
7874         -1.0,    1.0,   0.1,   -0.2,    1.2,
7875          1.0,    1.0,   0.1,    1.2,    1.2
7876     };
7877     memset(&caps, 0, sizeof(caps));
7878
7879     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7880     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7881     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7882         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7883         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7884            "Card has conditional NP2 support without power of two restriction set\n");
7885         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7886         return;
7887     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7888         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7889         return;
7890     }
7891
7892     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7893     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7894
7895     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7896     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7897
7898     memset(&rect, 0, sizeof(rect));
7899     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7900     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7901     for(y = 0; y < 10; y++) {
7902         for(x = 0; x < 10; x++) {
7903             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7904             if(x == 0 || x == 9 || y == 0 || y == 9) {
7905                 *dst = 0x00ff0000;
7906             } else {
7907                 *dst = 0x000000ff;
7908             }
7909         }
7910     }
7911     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7912     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7913
7914     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7915     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7916     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7917     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7918     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7919     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7920     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7921     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7922
7923     hr = IDirect3DDevice9_BeginScene(device);
7924     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7925     if(SUCCEEDED(hr)) {
7926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7927         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7928
7929         hr = IDirect3DDevice9_EndScene(device);
7930         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7931     }
7932
7933     color = getPixelColor(device,    1,  1);
7934     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7935     color = getPixelColor(device, 639, 479);
7936     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7937
7938     color = getPixelColor(device, 135, 101);
7939     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7940     color = getPixelColor(device, 140, 101);
7941     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7942     color = getPixelColor(device, 135, 105);
7943     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7944     color = getPixelColor(device, 140, 105);
7945     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7946
7947     color = getPixelColor(device, 135, 376);
7948     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7949     color = getPixelColor(device, 140, 376);
7950     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7951     color = getPixelColor(device, 135, 379);
7952     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7953     color = getPixelColor(device, 140, 379);
7954     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7955
7956     color = getPixelColor(device, 500, 101);
7957     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7958     color = getPixelColor(device, 504, 101);
7959     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7960     color = getPixelColor(device, 500, 105);
7961     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7962     color = getPixelColor(device, 504, 105);
7963     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7964
7965     color = getPixelColor(device, 500, 376);
7966     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7967     color = getPixelColor(device, 504, 376);
7968     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7969     color = getPixelColor(device, 500, 380);
7970     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7971     color = getPixelColor(device, 504, 380);
7972     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7973
7974     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7975
7976     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7977     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7978     IDirect3DTexture9_Release(texture);
7979 }
7980
7981 static void vFace_register_test(IDirect3DDevice9 *device)
7982 {
7983     HRESULT hr;
7984     DWORD color;
7985     const DWORD shader_code[] = {
7986         0xffff0300,                                                             /* ps_3_0                     */
7987         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7988         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7989         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7990         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7991         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7992         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7993         0x0000ffff                                                              /* END                        */
7994     };
7995     const DWORD vshader_code[] = {
7996         0xfffe0300,                                                             /* vs_3_0               */
7997         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7998         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7999         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8000         0x0000ffff                                                              /* end                  */
8001     };
8002     IDirect3DPixelShader9 *shader;
8003     IDirect3DVertexShader9 *vshader;
8004     IDirect3DTexture9 *texture;
8005     IDirect3DSurface9 *surface, *backbuffer;
8006     const float quad[] = {
8007         -1.0,   -1.0,   0.1,
8008          1.0,   -1.0,   0.1,
8009         -1.0,    0.0,   0.1,
8010
8011          1.0,   -1.0,   0.1,
8012          1.0,    0.0,   0.1,
8013         -1.0,    0.0,   0.1,
8014
8015         -1.0,    0.0,   0.1,
8016         -1.0,    1.0,   0.1,
8017          1.0,    0.0,   0.1,
8018
8019          1.0,    0.0,   0.1,
8020         -1.0,    1.0,   0.1,
8021          1.0,    1.0,   0.1,
8022     };
8023     const float blit[] = {
8024          0.0,   -1.0,   0.1,    0.0,    0.0,
8025          1.0,   -1.0,   0.1,    1.0,    0.0,
8026          0.0,    1.0,   0.1,    0.0,    1.0,
8027          1.0,    1.0,   0.1,    1.0,    1.0,
8028     };
8029
8030     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8031     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8032     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8033     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8034     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8035     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8036     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8037     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8038     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8039     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8040     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8041     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8042     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8043     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8044     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8045     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8046
8047     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8048     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8049
8050     hr = IDirect3DDevice9_BeginScene(device);
8051     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8052     if(SUCCEEDED(hr)) {
8053         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8054         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8055         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8056         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8057         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8058         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8059         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8060         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8061         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8063         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8064
8065         /* Blit the texture onto the back buffer to make it visible */
8066         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8067         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8068         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8069         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8070         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8071         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8072         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8073         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8074         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8075         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8076         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8077         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8078
8079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8080         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8081
8082         hr = IDirect3DDevice9_EndScene(device);
8083         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8084     }
8085
8086     color = getPixelColor(device, 160, 360);
8087     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8088     color = getPixelColor(device, 160, 120);
8089     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8090     color = getPixelColor(device, 480, 360);
8091     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8092     color = getPixelColor(device, 480, 120);
8093     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8094     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8095
8096     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8097     IDirect3DDevice9_SetTexture(device, 0, NULL);
8098     IDirect3DPixelShader9_Release(shader);
8099     IDirect3DVertexShader9_Release(vshader);
8100     IDirect3DSurface9_Release(surface);
8101     IDirect3DSurface9_Release(backbuffer);
8102     IDirect3DTexture9_Release(texture);
8103 }
8104
8105 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8106 {
8107     HRESULT hr;
8108     DWORD color;
8109     int i;
8110     D3DCAPS9 caps;
8111     BOOL L6V5U5_supported = FALSE;
8112     IDirect3DTexture9 *tex1, *tex2;
8113     D3DLOCKED_RECT locked_rect;
8114
8115     static const float quad[][7] = {
8116         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8117         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8118         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8119         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8120     };
8121
8122     static const D3DVERTEXELEMENT9 decl_elements[] = {
8123         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8124         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8125         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8126         D3DDECL_END()
8127     };
8128
8129     /* use asymmetric matrix to test loading */
8130     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8131     float scale, offset;
8132
8133     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8134     IDirect3DTexture9           *texture            = NULL;
8135
8136     memset(&caps, 0, sizeof(caps));
8137     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8138     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8139     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8140         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8141         return;
8142     } else {
8143         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8144          * They report that it is not supported, but after that bump mapping works properly. So just test
8145          * if the format is generally supported, and check the BUMPENVMAP flag
8146          */
8147         IDirect3D9 *d3d9;
8148
8149         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8150         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8151                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8152         L6V5U5_supported = SUCCEEDED(hr);
8153         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8154                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8155         IDirect3D9_Release(d3d9);
8156         if(FAILED(hr)) {
8157             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8158             return;
8159         }
8160     }
8161
8162     /* Generate the textures */
8163     generate_bumpmap_textures(device);
8164
8165     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8166     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8167     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8168     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8169     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8170     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8171     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8172     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8173
8174     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8175     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8176     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8177     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8178     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8179     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8180
8181     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8182     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8183     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8184     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8185     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8186     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8187
8188     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8189     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8190
8191     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8192     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8193
8194     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8195     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8196
8197
8198     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8199     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8200     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8201     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8202
8203     hr = IDirect3DDevice9_BeginScene(device);
8204     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8205
8206     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8207     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8208
8209     hr = IDirect3DDevice9_EndScene(device);
8210     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8211
8212     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8213      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8214      * But since testing the color match is not the purpose of the test don't be too picky
8215      */
8216     color = getPixelColor(device, 320-32, 240);
8217     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8218     color = getPixelColor(device, 320+32, 240);
8219     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8220     color = getPixelColor(device, 320, 240-32);
8221     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8222     color = getPixelColor(device, 320, 240+32);
8223     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8224     color = getPixelColor(device, 320, 240);
8225     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8226     color = getPixelColor(device, 320+32, 240+32);
8227     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8228     color = getPixelColor(device, 320-32, 240+32);
8229     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8230     color = getPixelColor(device, 320+32, 240-32);
8231     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8232     color = getPixelColor(device, 320-32, 240-32);
8233     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8234     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8235     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8236
8237     for(i = 0; i < 2; i++) {
8238         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8239         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8240         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8241         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8242         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8243         IDirect3DTexture9_Release(texture); /* To destroy it */
8244     }
8245
8246     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8247         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8248         goto cleanup;
8249     }
8250     if(L6V5U5_supported == FALSE) {
8251         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8252         goto cleanup;
8253     }
8254
8255     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8256     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8257     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8258      * would only make this test more complicated
8259      */
8260     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8261     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8262     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8263     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8264
8265     memset(&locked_rect, 0, sizeof(locked_rect));
8266     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8267     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8268     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8269     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8270     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8271
8272     memset(&locked_rect, 0, sizeof(locked_rect));
8273     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8274     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8275     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8276     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8277     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8278
8279     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8280     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8281     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8282     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8283
8284     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8285     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8286     scale = 2.0;
8287     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8288     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8289     offset = 0.1;
8290     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8291     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8292
8293     hr = IDirect3DDevice9_BeginScene(device);
8294     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8295     if(SUCCEEDED(hr)) {
8296         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8297         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8298         hr = IDirect3DDevice9_EndScene(device);
8299         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8300     }
8301
8302     color = getPixelColor(device, 320, 240);
8303     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8304      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8305      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8306      */
8307     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8308     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8309     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8310
8311     /* Check a result scale factor > 1.0 */
8312     scale = 10;
8313     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8314     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8315     offset = 10;
8316     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8317     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8318
8319     hr = IDirect3DDevice9_BeginScene(device);
8320     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8321     if(SUCCEEDED(hr)) {
8322         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8323         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8324         hr = IDirect3DDevice9_EndScene(device);
8325         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8326     }
8327     color = getPixelColor(device, 320, 240);
8328     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8329     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8330     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8331
8332     /* Check clamping in the scale factor calculation */
8333     scale = 1000;
8334     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8335     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8336     offset = -1;
8337     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8338     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8339
8340     hr = IDirect3DDevice9_BeginScene(device);
8341     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8342     if(SUCCEEDED(hr)) {
8343         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8344         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8345         hr = IDirect3DDevice9_EndScene(device);
8346         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8347     }
8348     color = getPixelColor(device, 320, 240);
8349     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8350     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8351     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8352
8353     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8354     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8355     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8356     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8357
8358     IDirect3DTexture9_Release(tex1);
8359     IDirect3DTexture9_Release(tex2);
8360
8361 cleanup:
8362     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8363     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8364     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8365     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8366
8367     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8368     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8369     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8370 }
8371
8372 static void stencil_cull_test(IDirect3DDevice9 *device) {
8373     HRESULT hr;
8374     IDirect3DSurface9 *depthstencil = NULL;
8375     D3DSURFACE_DESC desc;
8376     float quad1[] = {
8377         -1.0,   -1.0,   0.1,
8378          0.0,   -1.0,   0.1,
8379         -1.0,    0.0,   0.1,
8380          0.0,    0.0,   0.1,
8381     };
8382     float quad2[] = {
8383          0.0,   -1.0,   0.1,
8384          1.0,   -1.0,   0.1,
8385          0.0,    0.0,   0.1,
8386          1.0,    0.0,   0.1,
8387     };
8388     float quad3[] = {
8389         0.0,    0.0,   0.1,
8390         1.0,    0.0,   0.1,
8391         0.0,    1.0,   0.1,
8392         1.0,    1.0,   0.1,
8393     };
8394     float quad4[] = {
8395         -1.0,    0.0,   0.1,
8396          0.0,    0.0,   0.1,
8397         -1.0,    1.0,   0.1,
8398          0.0,    1.0,   0.1,
8399     };
8400     struct vertex painter[] = {
8401        {-1.0,   -1.0,   0.0,    0x00000000},
8402        { 1.0,   -1.0,   0.0,    0x00000000},
8403        {-1.0,    1.0,   0.0,    0x00000000},
8404        { 1.0,    1.0,   0.0,    0x00000000},
8405     };
8406     WORD indices_cw[]  = {0, 1, 3};
8407     WORD indices_ccw[] = {0, 2, 3};
8408     unsigned int i;
8409     DWORD color;
8410
8411     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8412     if(depthstencil == NULL) {
8413         skip("No depth stencil buffer\n");
8414         return;
8415     }
8416     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8417     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8418     IDirect3DSurface9_Release(depthstencil);
8419     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8420         skip("No 4 or 8 bit stencil surface\n");
8421         return;
8422     }
8423
8424     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8425     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8426     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8427
8428     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8429     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8430     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8431     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8432     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8433     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8434     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8435     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8436
8437     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8438     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8439     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8440     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8441     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8442     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8443
8444     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8445     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8446     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8447     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8448
8449     /* First pass: Fill the stencil buffer with some values... */
8450     hr = IDirect3DDevice9_BeginScene(device);
8451     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8452     if(SUCCEEDED(hr))
8453     {
8454         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8455         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8456         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8457                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8458         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8459         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8460                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8461         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8462
8463         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8464         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8465         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8466         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8467         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8468                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8469         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8470         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8471                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8472         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8473
8474         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8475         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8476         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8477                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8478         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8479         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8480                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8481         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8482
8483         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8484         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8485         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8486                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8487         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8488         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8489                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8490         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8491
8492         hr = IDirect3DDevice9_EndScene(device);
8493         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8494     }
8495
8496     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8497     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8498     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8499     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8500     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8501     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8502     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8503     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8504     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8507     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8508     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8509
8510     /* 2nd pass: Make the stencil values visible */
8511     hr = IDirect3DDevice9_BeginScene(device);
8512     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8513     if(SUCCEEDED(hr))
8514     {
8515         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8516         for(i = 0; i < 16; i++) {
8517             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8518             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8519
8520             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8521             painter[1].diffuse = (i * 16);
8522             painter[2].diffuse = (i * 16);
8523             painter[3].diffuse = (i * 16);
8524             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8525             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8526         }
8527         hr = IDirect3DDevice9_EndScene(device);
8528         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8529     }
8530
8531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8532     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8533
8534     color = getPixelColor(device, 160, 420);
8535     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8536     color = getPixelColor(device, 160, 300);
8537     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8538
8539     color = getPixelColor(device, 480, 420);
8540     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8541     color = getPixelColor(device, 480, 300);
8542     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8543
8544     color = getPixelColor(device, 160, 180);
8545     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8546     color = getPixelColor(device, 160, 60);
8547     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8548
8549     color = getPixelColor(device, 480, 180);
8550     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8551     color = getPixelColor(device, 480, 60);
8552     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8553
8554     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8555     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8556 }
8557
8558 static void vpos_register_test(IDirect3DDevice9 *device)
8559 {
8560     HRESULT hr;
8561     DWORD color;
8562     const DWORD shader_code[] = {
8563     0xffff0300,                                                             /* ps_3_0                     */
8564     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8565     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8566     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8567     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8568     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8569     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8570     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8571     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8572     0x0000ffff                                                              /* end                        */
8573     };
8574     const DWORD shader_frac_code[] = {
8575     0xffff0300,                                                             /* ps_3_0                     */
8576     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8577     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8578     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8579     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8580     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8581     0x0000ffff                                                              /* end                        */
8582     };
8583     const DWORD vshader_code[] = {
8584         0xfffe0300,                                                             /* vs_3_0               */
8585         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8586         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8587         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8588         0x0000ffff                                                              /* end                  */
8589     };
8590     IDirect3DVertexShader9 *vshader;
8591     IDirect3DPixelShader9 *shader, *shader_frac;
8592     IDirect3DSurface9 *surface = NULL, *backbuffer;
8593     const float quad[] = {
8594         -1.0,   -1.0,   0.1,    0.0,    0.0,
8595          1.0,   -1.0,   0.1,    1.0,    0.0,
8596         -1.0,    1.0,   0.1,    0.0,    1.0,
8597          1.0,    1.0,   0.1,    1.0,    1.0,
8598     };
8599     D3DLOCKED_RECT lr;
8600     float constant[4] = {1.0, 0.0, 320, 240};
8601     DWORD *pos;
8602
8603     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8604     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8605     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8606     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8607     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8608     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8609     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8610     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8611     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8612     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8613     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8614     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8615     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8616     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8617     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8618     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8619
8620     hr = IDirect3DDevice9_BeginScene(device);
8621     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8622     if(SUCCEEDED(hr)) {
8623         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8624         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8625         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8626         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8627         hr = IDirect3DDevice9_EndScene(device);
8628         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8629     }
8630
8631     /* This has to be pixel exact */
8632     color = getPixelColor(device, 319, 239);
8633     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8634     color = getPixelColor(device, 320, 239);
8635     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8636     color = getPixelColor(device, 319, 240);
8637     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8638     color = getPixelColor(device, 320, 240);
8639     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8640     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8641
8642     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8643                                              &surface, NULL);
8644     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8645     hr = IDirect3DDevice9_BeginScene(device);
8646     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8647     if(SUCCEEDED(hr)) {
8648         constant[2] = 16; constant[3] = 16;
8649         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8650         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8651         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8652         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8653         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8654         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8655         hr = IDirect3DDevice9_EndScene(device);
8656         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8657     }
8658     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8659     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8660
8661     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8662     color = *pos & 0x00ffffff;
8663     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8664     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8665     color = *pos & 0x00ffffff;
8666     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8667     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8668     color = *pos & 0x00ffffff;
8669     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8670     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8671     color = *pos & 0x00ffffff;
8672     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8673
8674     hr = IDirect3DSurface9_UnlockRect(surface);
8675     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8676
8677     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8678      * have full control over the multisampling setting inside this test
8679      */
8680     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8681     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8682     hr = IDirect3DDevice9_BeginScene(device);
8683     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8684     if(SUCCEEDED(hr)) {
8685         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8686         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8687         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8688         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8689         hr = IDirect3DDevice9_EndScene(device);
8690         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8691     }
8692     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8693     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8694
8695     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8696     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8697
8698     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8699     color = *pos & 0x00ffffff;
8700     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8701
8702     hr = IDirect3DSurface9_UnlockRect(surface);
8703     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8704
8705     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8706     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8707     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8708     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8709     IDirect3DPixelShader9_Release(shader);
8710     IDirect3DPixelShader9_Release(shader_frac);
8711     IDirect3DVertexShader9_Release(vshader);
8712     if(surface) IDirect3DSurface9_Release(surface);
8713     IDirect3DSurface9_Release(backbuffer);
8714 }
8715
8716 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8717 {
8718     D3DCOLOR color;
8719
8720     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8721     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8722     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8723     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8724     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8725
8726     ++r;
8727     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8728     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8729     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8730     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8731     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8732
8733     return TRUE;
8734 }
8735
8736 static void pointsize_test(IDirect3DDevice9 *device)
8737 {
8738     HRESULT hr;
8739     D3DCAPS9 caps;
8740     D3DMATRIX matrix;
8741     D3DMATRIX identity;
8742     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8743     DWORD color;
8744     IDirect3DSurface9 *rt, *backbuffer;
8745     IDirect3DTexture9 *tex1, *tex2;
8746     RECT rect = {0, 0, 128, 128};
8747     D3DLOCKED_RECT lr;
8748     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8749                                 0x00000000, 0x00000000};
8750     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8751                                 0x00000000, 0x0000ff00};
8752
8753     const float vertices[] = {
8754         64,     64,     0.1,
8755         128,    64,     0.1,
8756         192,    64,     0.1,
8757         256,    64,     0.1,
8758         320,    64,     0.1,
8759         384,    64,     0.1,
8760         448,    64,     0.1,
8761         512,    64,     0.1,
8762     };
8763
8764     /* 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 */
8765     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;
8766     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;
8767     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;
8768     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;
8769
8770     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;
8771     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;
8772     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;
8773     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;
8774
8775     memset(&caps, 0, sizeof(caps));
8776     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8777     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8778     if(caps.MaxPointSize < 32.0) {
8779         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8780         return;
8781     }
8782
8783     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8784     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8785     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8786     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8787     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8788     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8789     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8790     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8791
8792     hr = IDirect3DDevice9_BeginScene(device);
8793     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8794     if (SUCCEEDED(hr))
8795     {
8796         ptsize = 15.0;
8797         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8798         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8799         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8800         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8801
8802         ptsize = 31.0;
8803         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8804         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8805         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8806         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8807
8808         ptsize = 30.75;
8809         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8810         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8813
8814         if (caps.MaxPointSize >= 63.0)
8815         {
8816             ptsize = 63.0;
8817             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8818             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8819             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8820             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8821
8822             ptsize = 62.75;
8823             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8824             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8825             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8826             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8827         }
8828
8829         ptsize = 1.0;
8830         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8831         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8832         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8833         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8834
8835         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8836         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8837         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8838         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8839
8840         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8841         ptsize = 15.0;
8842         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8843         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8844         ptsize = 1.0;
8845         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8846         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8848         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8849
8850         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8851         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8852
8853         /* pointsize < pointsize_min < pointsize_max?
8854          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8855         ptsize = 1.0;
8856         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8857         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8858         ptsize = 15.0;
8859         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8860         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8861         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8862         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8863
8864         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8865         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8866
8867         hr = IDirect3DDevice9_EndScene(device);
8868         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8869     }
8870
8871     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8872     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8873     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8874
8875     if (caps.MaxPointSize >= 63.0)
8876     {
8877         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8878         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8879     }
8880
8881     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8882     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8883     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8884     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8885     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8886
8887     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8888
8889     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8890      * generates texture coordinates for the point(result: Yes, it does)
8891      *
8892      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8893      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8894      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8895      */
8896     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8897     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8898
8899     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8901     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8903     memset(&lr, 0, sizeof(lr));
8904     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8905     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8906     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8907     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8908     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8909     memset(&lr, 0, sizeof(lr));
8910     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8911     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8912     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8913     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8914     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8915     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8916     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8917     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8918     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8919     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8920     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8921     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8922     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8923     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8924     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8925     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8926     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8927     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8928     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8929
8930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8931     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8932     ptsize = 32.0;
8933     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8934     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8935
8936     hr = IDirect3DDevice9_BeginScene(device);
8937     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8938     if(SUCCEEDED(hr))
8939     {
8940         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8941         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8942         hr = IDirect3DDevice9_EndScene(device);
8943         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8944     }
8945
8946     color = getPixelColor(device, 64-4, 64-4);
8947     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8948     color = getPixelColor(device, 64-4, 64+4);
8949     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8950     color = getPixelColor(device, 64+4, 64+4);
8951     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8952     color = getPixelColor(device, 64+4, 64-4);
8953     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8954     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8955
8956     U(matrix).m[0][0] =  1.0f / 64.0f;
8957     U(matrix).m[1][1] = -1.0f / 64.0f;
8958     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8959     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8960
8961     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8962     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8963
8964     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8965             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8966     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8967
8968     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8969     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8970     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8971     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8972
8973     hr = IDirect3DDevice9_BeginScene(device);
8974     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8975     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8976     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8977     hr = IDirect3DDevice9_EndScene(device);
8978     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8979
8980     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8981     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8982     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8983     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8984     IDirect3DSurface9_Release(backbuffer);
8985     IDirect3DSurface9_Release(rt);
8986
8987     color = getPixelColor(device, 64-4, 64-4);
8988     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8989             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8990     color = getPixelColor(device, 64+4, 64-4);
8991     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8992             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8993     color = getPixelColor(device, 64-4, 64+4);
8994     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8995             "Expected color 0x00000000, got 0x%08x.\n", color);
8996     color = getPixelColor(device, 64+4, 64+4);
8997     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8998             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8999
9000     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9001     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9002
9003     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9004     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9005     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9006     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9007     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9008     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9009     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9010     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9011     IDirect3DTexture9_Release(tex1);
9012     IDirect3DTexture9_Release(tex2);
9013
9014     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9015     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9016     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9017     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9018     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9019     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9020 }
9021
9022 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9023 {
9024     static const DWORD vshader_code[] =
9025     {
9026         0xfffe0300,                                                             /* vs_3_0                     */
9027         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9028         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9029         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9030         0x0000ffff                                                              /* end                        */
9031     };
9032     static const DWORD pshader_code[] =
9033     {
9034         0xffff0300,                                                             /* ps_3_0                     */
9035         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9036         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9037         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9038         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9039         0x0000ffff                                                              /* end                        */
9040     };
9041
9042     HRESULT hr;
9043     IDirect3DVertexShader9 *vs;
9044     IDirect3DPixelShader9 *ps;
9045     IDirect3DTexture9 *tex1, *tex2;
9046     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9047     D3DCAPS9 caps;
9048     DWORD color;
9049     float quad[] = {
9050        -1.0,   -1.0,    0.1,
9051         1.0,   -1.0,    0.1,
9052        -1.0,    1.0,    0.1,
9053         1.0,    1.0,    0.1,
9054     };
9055     float texquad[] = {
9056        -1.0,   -1.0,    0.1,    0.0,    0.0,
9057         0.0,   -1.0,    0.1,    1.0,    0.0,
9058        -1.0,    1.0,    0.1,    0.0,    1.0,
9059         0.0,    1.0,    0.1,    1.0,    1.0,
9060
9061         0.0,   -1.0,    0.1,    0.0,    0.0,
9062         1.0,   -1.0,    0.1,    1.0,    0.0,
9063         0.0,    1.0,    0.1,    0.0,    1.0,
9064         1.0,    1.0,    0.1,    1.0,    1.0,
9065     };
9066
9067     memset(&caps, 0, sizeof(caps));
9068     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9069     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9070     if(caps.NumSimultaneousRTs < 2) {
9071         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9072         return;
9073     }
9074
9075     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9076     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9077
9078     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9079             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9080     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9081
9082     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9083             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9084     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9085     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9086             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9087     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9088     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9089     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9090     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
9091     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9092
9093     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9094     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9095     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9096     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9097     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9098     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9099
9100     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9101     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9102     hr = IDirect3DDevice9_SetPixelShader(device, ps);
9103     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9104     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9105     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9106     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9107     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9108     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9109     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9110
9111     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9112     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9113     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9114     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9115     color = getPixelColorFromSurface(readback, 8, 8);
9116     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9117             "Expected color 0x000000ff, got 0x%08x.\n", color);
9118     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9119     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9120     color = getPixelColorFromSurface(readback, 8, 8);
9121     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9122             "Expected color 0x000000ff, got 0x%08x.\n", color);
9123
9124     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9125     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9126     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9127     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9128     color = getPixelColorFromSurface(readback, 8, 8);
9129     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9130             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9131     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9132     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9133     color = getPixelColorFromSurface(readback, 8, 8);
9134     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9135             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9136
9137     hr = IDirect3DDevice9_BeginScene(device);
9138     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9139     if(SUCCEEDED(hr)) {
9140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9142
9143         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9144         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9145         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9146         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9147         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9148         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9149         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9150         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9151         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9152         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9153
9154         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9155         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9157         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9158
9159         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9160         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9162         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9163
9164         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9165         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9166
9167         hr = IDirect3DDevice9_EndScene(device);
9168         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9169     }
9170
9171     color = getPixelColor(device, 160, 240);
9172     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9173     color = getPixelColor(device, 480, 240);
9174     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9175     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9176
9177     IDirect3DPixelShader9_Release(ps);
9178     IDirect3DVertexShader9_Release(vs);
9179     IDirect3DTexture9_Release(tex1);
9180     IDirect3DTexture9_Release(tex2);
9181     IDirect3DSurface9_Release(surf1);
9182     IDirect3DSurface9_Release(surf2);
9183     IDirect3DSurface9_Release(backbuf);
9184     IDirect3DSurface9_Release(readback);
9185 }
9186
9187 struct formats {
9188     const char *fmtName;
9189     D3DFORMAT textureFormat;
9190     DWORD resultColorBlending;
9191     DWORD resultColorNoBlending;
9192 };
9193
9194 const struct formats test_formats[] = {
9195   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9196   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9197   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9198   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9199   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9200   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9201   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9202   { NULL, 0 }
9203 };
9204
9205 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9206 {
9207     HRESULT hr;
9208     IDirect3DTexture9 *offscreenTexture = NULL;
9209     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9210     IDirect3D9 *d3d = NULL;
9211     DWORD color;
9212     DWORD r0, g0, b0, r1, g1, b1;
9213     int fmt_index;
9214
9215     static const float quad[][5] = {
9216         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9217         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9218         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9219         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9220     };
9221
9222     /* Quad with R=0x10, G=0x20 */
9223     static const struct vertex quad1[] = {
9224         {-1.0f, -1.0f, 0.1f, 0x80102000},
9225         {-1.0f,  1.0f, 0.1f, 0x80102000},
9226         { 1.0f, -1.0f, 0.1f, 0x80102000},
9227         { 1.0f,  1.0f, 0.1f, 0x80102000},
9228     };
9229
9230     /* Quad with R=0x20, G=0x10 */
9231     static const struct vertex quad2[] = {
9232         {-1.0f, -1.0f, 0.1f, 0x80201000},
9233         {-1.0f,  1.0f, 0.1f, 0x80201000},
9234         { 1.0f, -1.0f, 0.1f, 0x80201000},
9235         { 1.0f,  1.0f, 0.1f, 0x80201000},
9236     };
9237
9238     IDirect3DDevice9_GetDirect3D(device, &d3d);
9239
9240     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9241     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9242     if(!backbuffer) {
9243         goto out;
9244     }
9245
9246     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9247     {
9248         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9249         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9250            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9251            continue;
9252         }
9253
9254         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9255         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9256
9257         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9258         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9259         if(!offscreenTexture) {
9260             continue;
9261         }
9262
9263         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9264         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9265         if(!offscreen) {
9266             continue;
9267         }
9268
9269         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9270         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9271
9272         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9273         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9274         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9275         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9276         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9277         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9278         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9279         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9280         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9281         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9282
9283         /* Below we will draw two quads with different colors and try to blend them together.
9284          * The result color is compared with the expected outcome.
9285          */
9286         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9287             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9288             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9289             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9290             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9291
9292             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9293             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9294
9295             /* Draw a quad using color 0x0010200 */
9296             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9297             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9298             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9299             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9300             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9301             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9302
9303             /* Draw a quad using color 0x0020100 */
9304             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9305             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9306             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9307             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9308             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9309             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9310
9311             /* We don't want to blend the result on the backbuffer */
9312             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9313             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9314
9315             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9316             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9317             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9318             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9319             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9320
9321             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9322             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9323
9324             /* This time with the texture */
9325             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9326             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9327
9328             IDirect3DDevice9_EndScene(device);
9329         }
9330
9331         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9332             /* Compare the color of the center quad with our expectation */
9333             color = getPixelColor(device, 320, 240);
9334             r0 = (color & 0x00ff0000) >> 16;
9335             g0 = (color & 0x0000ff00) >>  8;
9336             b0 = (color & 0x000000ff) >>  0;
9337
9338             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9339             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9340             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9341
9342             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9343                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9344                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9345                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9346         } else {
9347             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9348              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9349              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9350             color = getPixelColor(device, 320, 240);
9351             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);
9352         }
9353         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9354
9355         IDirect3DDevice9_SetTexture(device, 0, NULL);
9356         if(offscreenTexture) {
9357             IDirect3DTexture9_Release(offscreenTexture);
9358         }
9359         if(offscreen) {
9360             IDirect3DSurface9_Release(offscreen);
9361         }
9362     }
9363
9364 out:
9365     /* restore things */
9366     if(backbuffer) {
9367         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9368         IDirect3DSurface9_Release(backbuffer);
9369     }
9370 }
9371
9372 static void tssargtemp_test(IDirect3DDevice9 *device)
9373 {
9374     HRESULT hr;
9375     DWORD color;
9376     static const struct vertex quad[] = {
9377         {-1.0,     -1.0,    0.1,    0x00ff0000},
9378         { 1.0,     -1.0,    0.1,    0x00ff0000},
9379         {-1.0,      1.0,    0.1,    0x00ff0000},
9380         { 1.0,      1.0,    0.1,    0x00ff0000}
9381     };
9382     D3DCAPS9 caps;
9383
9384     memset(&caps, 0, sizeof(caps));
9385     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9386     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9387     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9388         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9389         return;
9390     }
9391
9392     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9393     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9394
9395     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9396     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9397     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9398     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9399
9400     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9401     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9402     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9403     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9404     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9405     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9406
9407     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9408     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9409     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9410     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9411     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9412     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9413
9414     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9415     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9416
9417     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9418     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9419     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9420     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9421
9422     hr = IDirect3DDevice9_BeginScene(device);
9423     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9424     if(SUCCEEDED(hr)) {
9425         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9426         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9427         hr = IDirect3DDevice9_EndScene(device);
9428         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9429     }
9430     color = getPixelColor(device, 320, 240);
9431     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9432     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9433
9434     /* Set stage 1 back to default */
9435     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9436     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9437     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9438     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9439     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9440     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9441     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9442     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9443     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9444     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9445 }
9446
9447 struct testdata
9448 {
9449     DWORD idxVertex; /* number of instances in the first stream */
9450     DWORD idxColor; /* number of instances in the second stream */
9451     DWORD idxInstance; /* should be 1 ?? */
9452     DWORD color1; /* color 1 instance */
9453     DWORD color2; /* color 2 instance */
9454     DWORD color3; /* color 3 instance */
9455     DWORD color4; /* color 4 instance */
9456     WORD strVertex; /* specify which stream to use 0-2*/
9457     WORD strColor;
9458     WORD strInstance;
9459 };
9460
9461 static const struct testdata testcases[]=
9462 {
9463     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9464     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9465     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9466     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9467     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9468     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9469     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9470     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9471     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9472     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9473     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9474     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9475     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9476     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9477     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9478 /*
9479     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9480     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9481 */
9482 };
9483
9484 /* Drawing Indexed Geometry with instances*/
9485 static void stream_test(IDirect3DDevice9 *device)
9486 {
9487     IDirect3DVertexBuffer9 *vb = NULL;
9488     IDirect3DVertexBuffer9 *vb2 = NULL;
9489     IDirect3DVertexBuffer9 *vb3 = NULL;
9490     IDirect3DIndexBuffer9 *ib = NULL;
9491     IDirect3DVertexDeclaration9 *pDecl = NULL;
9492     IDirect3DVertexShader9 *shader = NULL;
9493     HRESULT hr;
9494     BYTE *data;
9495     DWORD color;
9496     DWORD ind;
9497     unsigned i;
9498
9499     const DWORD shader_code[] =
9500     {
9501         0xfffe0101,                                     /* vs_1_1 */
9502         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9503         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9504         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9505         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9506         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9507         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9508         0x0000ffff
9509     };
9510
9511     const float quad[][3] =
9512     {
9513         {-0.5f, -0.5f,  1.1f}, /*0 */
9514         {-0.5f,  0.5f,  1.1f}, /*1 */
9515         { 0.5f, -0.5f,  1.1f}, /*2 */
9516         { 0.5f,  0.5f,  1.1f}, /*3 */
9517     };
9518
9519     const float vertcolor[][4] =
9520     {
9521         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9522         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9523         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9524         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9525     };
9526
9527     /* 4 position for 4 instances */
9528     const float instancepos[][3] =
9529     {
9530         {-0.6f,-0.6f, 0.0f},
9531         { 0.6f,-0.6f, 0.0f},
9532         { 0.6f, 0.6f, 0.0f},
9533         {-0.6f, 0.6f, 0.0f},
9534     };
9535
9536     short indices[] = {0, 1, 2, 1, 2, 3};
9537
9538     D3DVERTEXELEMENT9 decl[] =
9539     {
9540         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9541         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9542         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9543         D3DDECL_END()
9544     };
9545
9546     /* set the default value because it isn't done in wine? */
9547     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9548     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9549
9550     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9551     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9552     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9553
9554     /* check wrong cases */
9555     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9556     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9557     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9558     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9559     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9560     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9561     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9562     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9563     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9564     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9565     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9566     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9567     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9568     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9569     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9570     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9571     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9572     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9573     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9574     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9575
9576     /* set the default value back */
9577     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9578     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9579
9580     /* create all VertexBuffers*/
9581     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9582     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9583     if(!vb) {
9584         skip("Failed to create a vertex buffer\n");
9585         return;
9586     }
9587     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9588     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9589     if(!vb2) {
9590         skip("Failed to create a vertex buffer\n");
9591         goto out;
9592     }
9593     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9594     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9595     if(!vb3) {
9596         skip("Failed to create a vertex buffer\n");
9597         goto out;
9598     }
9599
9600     /* create IndexBuffer*/
9601     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9602     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9603     if(!ib) {
9604         skip("Failed to create a index buffer\n");
9605         goto out;
9606     }
9607
9608     /* copy all Buffers (Vertex + Index)*/
9609     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9610     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9611     memcpy(data, quad, sizeof(quad));
9612     hr = IDirect3DVertexBuffer9_Unlock(vb);
9613     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9614     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9615     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9616     memcpy(data, vertcolor, sizeof(vertcolor));
9617     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9618     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9619     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9620     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9621     memcpy(data, instancepos, sizeof(instancepos));
9622     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9623     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9624     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9625     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9626     memcpy(data, indices, sizeof(indices));
9627     hr = IDirect3DIndexBuffer9_Unlock(ib);
9628     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9629
9630     /* create VertexShader */
9631     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9632     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9633     if(!shader) {
9634         skip("Failed to create a vetex shader\n");
9635         goto out;
9636     }
9637
9638     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9639     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9640
9641     hr = IDirect3DDevice9_SetIndices(device, ib);
9642     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9643
9644     /* run all tests */
9645     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9646     {
9647         struct testdata act = testcases[i];
9648         decl[0].Stream = act.strVertex;
9649         decl[1].Stream = act.strColor;
9650         decl[2].Stream = act.strInstance;
9651         /* create VertexDeclarations */
9652         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9653         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9654
9655         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9656         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9657
9658         hr = IDirect3DDevice9_BeginScene(device);
9659         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9660         if(SUCCEEDED(hr))
9661         {
9662             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9663             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9664
9665             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9666             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9667             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9668             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9669
9670             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9671             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9672             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9673             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9674
9675             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9676             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9677             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9678             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9679
9680             /* don't know if this is right (1*3 and 4*1)*/
9681             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9682             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9683             hr = IDirect3DDevice9_EndScene(device);
9684             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9685
9686             /* set all StreamSource && StreamSourceFreq back to default */
9687             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9688             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9689             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9690             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9691             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9692             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9693             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9694             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9695             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9696             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9697             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9698             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9699         }
9700
9701         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9702         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9703
9704         color = getPixelColor(device, 160, 360);
9705         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9706         color = getPixelColor(device, 480, 360);
9707         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9708         color = getPixelColor(device, 480, 120);
9709         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9710         color = getPixelColor(device, 160, 120);
9711         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9712
9713         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9714         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9715     }
9716
9717     hr = IDirect3DDevice9_SetIndices(device, NULL);
9718     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9719
9720 out:
9721     if(vb) IDirect3DVertexBuffer9_Release(vb);
9722     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9723     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9724     if(ib)IDirect3DIndexBuffer9_Release(ib);
9725     if(shader)IDirect3DVertexShader9_Release(shader);
9726 }
9727
9728 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9729     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9730     IDirect3DTexture9 *dsttex = NULL;
9731     HRESULT hr;
9732     DWORD color;
9733     D3DRECT r1 = {0,  0,  50,  50 };
9734     D3DRECT r2 = {50, 0,  100, 50 };
9735     D3DRECT r3 = {50, 50, 100, 100};
9736     D3DRECT r4 = {0,  50,  50, 100};
9737     const float quad[] = {
9738         -1.0,   -1.0,   0.1,    0.0,    0.0,
9739          1.0,   -1.0,   0.1,    1.0,    0.0,
9740         -1.0,    1.0,   0.1,    0.0,    1.0,
9741          1.0,    1.0,   0.1,    1.0,    1.0,
9742     };
9743
9744     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9745     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9746
9747     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9748     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9749     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9750     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9751
9752     if(!src || !dsttex) {
9753         skip("One or more test resources could not be created\n");
9754         goto cleanup;
9755     }
9756
9757     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9758     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9759
9760     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9761     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9762
9763     /* Clear the StretchRect destination for debugging */
9764     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9765     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9766     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9767     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9768
9769     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9770     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9771
9772     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9773     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9774     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9775     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9776     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9777     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9778     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9779     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9780
9781     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9782      * the target -> texture GL blit path
9783      */
9784     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9785     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9786     IDirect3DSurface9_Release(dst);
9787
9788     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9789     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9790
9791     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9792     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9793     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9794     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9795     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9796     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9797     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9798     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9799
9800     hr = IDirect3DDevice9_BeginScene(device);
9801     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9802     if(SUCCEEDED(hr)) {
9803         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9804         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9805         hr = IDirect3DDevice9_EndScene(device);
9806         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9807     }
9808
9809     color = getPixelColor(device, 160, 360);
9810     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9811     color = getPixelColor(device, 480, 360);
9812     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9813     color = getPixelColor(device, 480, 120);
9814     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9815     color = getPixelColor(device, 160, 120);
9816     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9817     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9818     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9819
9820     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9821     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9822     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9823     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9824
9825 cleanup:
9826     if(src) IDirect3DSurface9_Release(src);
9827     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9828     if(dsttex) IDirect3DTexture9_Release(dsttex);
9829 }
9830
9831 static void texop_test(IDirect3DDevice9 *device)
9832 {
9833     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9834     IDirect3DTexture9 *texture = NULL;
9835     D3DLOCKED_RECT locked_rect;
9836     D3DCOLOR color;
9837     D3DCAPS9 caps;
9838     HRESULT hr;
9839     unsigned i;
9840
9841     static const struct {
9842         float x, y, z;
9843         float s, t;
9844         D3DCOLOR diffuse;
9845     } quad[] = {
9846         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9847         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9848         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9849         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9850     };
9851
9852     static const D3DVERTEXELEMENT9 decl_elements[] = {
9853         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9854         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9855         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9856         D3DDECL_END()
9857     };
9858
9859     static const struct {
9860         D3DTEXTUREOP op;
9861         const char *name;
9862         DWORD caps_flag;
9863         D3DCOLOR result;
9864     } test_data[] = {
9865         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9866         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9867         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9868         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9869         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9870         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9871         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9872         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9873         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9874         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9875         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9876         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9877         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9878         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9879         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9880         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9881         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9882         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9883         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9884         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9885         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9886         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9887         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9888     };
9889
9890     memset(&caps, 0, sizeof(caps));
9891     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9892     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9893
9894     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9895     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9896     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9897     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9898
9899     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9900     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9901     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9902     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9903     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9904     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9905     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9906     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9907     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9908
9909     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9910     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9911     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9912     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9913     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9914     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9915
9916     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9917     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9918
9919     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9920     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9921     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9922     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9923     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9924     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9925
9926     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9927     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9928
9929     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9930     {
9931         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9932         {
9933             skip("tex operation %s not supported\n", test_data[i].name);
9934             continue;
9935         }
9936
9937         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9938         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9939
9940         hr = IDirect3DDevice9_BeginScene(device);
9941         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9942
9943         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9944         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9945
9946         hr = IDirect3DDevice9_EndScene(device);
9947         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9948
9949         color = getPixelColor(device, 320, 240);
9950         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9951                 test_data[i].name, color, test_data[i].result);
9952
9953         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9954         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9955     }
9956
9957     if (texture) IDirect3DTexture9_Release(texture);
9958     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9959 }
9960
9961 static void yuv_color_test(IDirect3DDevice9 *device) {
9962     HRESULT hr;
9963     IDirect3DSurface9 *surface = NULL, *target = NULL;
9964     unsigned int fmt, i;
9965     D3DFORMAT format;
9966     const char *fmt_string;
9967     D3DLOCKED_RECT lr;
9968     IDirect3D9 *d3d;
9969     HRESULT color;
9970     DWORD ref_color_left, ref_color_right;
9971
9972     struct {
9973         DWORD in;           /* The input color */
9974         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9975         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9976         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9977         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9978     } test_data[] = {
9979     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9980      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9981      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9982      * that
9983      */
9984       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9985       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9986       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9987       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9988       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9989       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9990       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9991       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9992       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9993       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9994       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9995       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9996       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9997       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9998
9999       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10000       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10001       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10002       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10003     };
10004
10005     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10006     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10007     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10008     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10009
10010     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10011     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10012
10013     for(fmt = 0; fmt < 2; fmt++) {
10014         if(fmt == 0) {
10015             format = D3DFMT_UYVY;
10016             fmt_string = "D3DFMT_UYVY";
10017         } else {
10018             format = D3DFMT_YUY2;
10019             fmt_string = "D3DFMT_YUY2";
10020         }
10021
10022         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10023                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10024                        */
10025         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10026                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10027             skip("%s is not supported\n", fmt_string);
10028             continue;
10029         }
10030
10031         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10032         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10033         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10034
10035         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10036             if(fmt == 0) {
10037                 ref_color_left = test_data[i].uyvy_left;
10038                 ref_color_right = test_data[i].uyvy_right;
10039             } else {
10040                 ref_color_left = test_data[i].yuy2_left;
10041                 ref_color_right = test_data[i].yuy2_right;
10042             }
10043
10044             memset(&lr, 0, sizeof(lr));
10045             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10046             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10047             *((DWORD *) lr.pBits) = test_data[i].in;
10048             hr = IDirect3DSurface9_UnlockRect(surface);
10049             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10050
10051             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10052             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10053             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10054             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10055
10056             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10057              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10058              * want to add tests for the filtered pixels as well.
10059              *
10060              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10061              * differently, so we need a max diff of 16
10062              */
10063             color = getPixelColor(device, 40, 240);
10064             ok(color_match(color, ref_color_left, 18),
10065                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10066                test_data[i].in, color, ref_color_left, fmt_string);
10067             color = getPixelColor(device, 600, 240);
10068             ok(color_match(color, ref_color_right, 18),
10069                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10070                test_data[i].in, color, ref_color_right, fmt_string);
10071             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10072             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10073         }
10074         IDirect3DSurface9_Release(surface);
10075     }
10076     IDirect3DSurface9_Release(target);
10077     IDirect3D9_Release(d3d);
10078 }
10079
10080 static void texop_range_test(IDirect3DDevice9 *device)
10081 {
10082     static const struct {
10083         float x, y, z;
10084         D3DCOLOR diffuse;
10085     } quad[] = {
10086         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10087         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10088         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10089         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10090     };
10091     HRESULT hr;
10092     IDirect3DTexture9 *texture;
10093     D3DLOCKED_RECT locked_rect;
10094     D3DCAPS9 caps;
10095     DWORD color;
10096
10097     /* We need ADD and SUBTRACT operations */
10098     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10099     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10100     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10101         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10102         return;
10103     }
10104     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10105         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10106         return;
10107     }
10108
10109     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10110     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10111     /* Stage 1: result = diffuse(=1.0) + diffuse
10112      * stage 2: result = result - tfactor(= 0.5)
10113      */
10114     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10115     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10116     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10117     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10118     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10119     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10120     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10121     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10122     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10123     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10124     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10125     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10126     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10127     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10128
10129     hr = IDirect3DDevice9_BeginScene(device);
10130     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10131     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10132     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10133     hr = IDirect3DDevice9_EndScene(device);
10134     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10135
10136     color = getPixelColor(device, 320, 240);
10137     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10138        color);
10139     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10140     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10141
10142     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10143     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10144     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10145     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10146     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10147     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10148     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10149     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10150     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10151
10152     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10153      * stage 2: result = result + diffuse(1.0)
10154      */
10155     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10156     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10157     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10158     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10159     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10160     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10161     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10162     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10163     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10164     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10165     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10166     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10167     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10168     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10169
10170     hr = IDirect3DDevice9_BeginScene(device);
10171     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10172     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10173     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10174     hr = IDirect3DDevice9_EndScene(device);
10175     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10176
10177     color = getPixelColor(device, 320, 240);
10178     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10179        color);
10180     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10181     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10182
10183     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10184     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10185     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10186     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10187     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10188     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10189     IDirect3DTexture9_Release(texture);
10190 }
10191
10192 static void alphareplicate_test(IDirect3DDevice9 *device) {
10193     struct vertex quad[] = {
10194         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10195         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10196         { -1.0,     1.0,    0.1,    0x80ff00ff },
10197         {  1.0,     1.0,    0.1,    0x80ff00ff },
10198     };
10199     HRESULT hr;
10200     DWORD color;
10201
10202     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10203     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10204
10205     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10206     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10207
10208     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10209     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10210     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10211     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10212
10213     hr = IDirect3DDevice9_BeginScene(device);
10214     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10215     if(SUCCEEDED(hr)) {
10216         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10217         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10218         hr = IDirect3DDevice9_EndScene(device);
10219         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10220     }
10221
10222     color = getPixelColor(device, 320, 240);
10223     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10224        color);
10225     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10226     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10227
10228     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10229     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10230
10231 }
10232
10233 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10234     HRESULT hr;
10235     D3DCAPS9 caps;
10236     DWORD color;
10237     struct vertex quad[] = {
10238         { -1.0,    -1.0,    0.1,    0x408080c0 },
10239         {  1.0,    -1.0,    0.1,    0x408080c0 },
10240         { -1.0,     1.0,    0.1,    0x408080c0 },
10241         {  1.0,     1.0,    0.1,    0x408080c0 },
10242     };
10243
10244     memset(&caps, 0, sizeof(caps));
10245     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10246     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10247     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10248         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10249         return;
10250     }
10251
10252     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10253     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10254
10255     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10256     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10257
10258     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10259      * mov r0.a, diffuse.a
10260      * mov r0, r0.a
10261      *
10262      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10263      * 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
10264      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10265      */
10266     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10267     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10268     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10269     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10270     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10272     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10274     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10275     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10276     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10277     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10278     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10279     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10280     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10281     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10282     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10283     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10284
10285     hr = IDirect3DDevice9_BeginScene(device);
10286     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10287     if(SUCCEEDED(hr)) {
10288         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10289         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10290         hr = IDirect3DDevice9_EndScene(device);
10291         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10292     }
10293
10294     color = getPixelColor(device, 320, 240);
10295     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10296        color);
10297     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10298     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10299
10300     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10301     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10302     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10303     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10304     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10305     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10306 }
10307
10308 static void zwriteenable_test(IDirect3DDevice9 *device) {
10309     HRESULT hr;
10310     DWORD color;
10311     struct vertex quad1[] = {
10312         { -1.0,  -1.0,  0.1,    0x00ff0000},
10313         { -1.0,   1.0,  0.1,    0x00ff0000},
10314         {  1.0,  -1.0,  0.1,    0x00ff0000},
10315         {  1.0,   1.0,  0.1,    0x00ff0000},
10316     };
10317     struct vertex quad2[] = {
10318         { -1.0,  -1.0,  0.9,    0x0000ff00},
10319         { -1.0,   1.0,  0.9,    0x0000ff00},
10320         {  1.0,  -1.0,  0.9,    0x0000ff00},
10321         {  1.0,   1.0,  0.9,    0x0000ff00},
10322     };
10323
10324     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10325     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10326
10327     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10328     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10329     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10330     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10331     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10332     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10333     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10334     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10335
10336     hr = IDirect3DDevice9_BeginScene(device);
10337     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10338     if(SUCCEEDED(hr)) {
10339         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10340          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10341          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10342          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10343          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10344          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10345          */
10346         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10347         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10348         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10349         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10351         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10352
10353         hr = IDirect3DDevice9_EndScene(device);
10354         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10355     }
10356
10357     color = getPixelColor(device, 320, 240);
10358     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10359        color);
10360     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10361     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10362
10363     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10364     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10365 }
10366
10367 static void alphatest_test(IDirect3DDevice9 *device) {
10368 #define ALPHATEST_PASSED 0x0000ff00
10369 #define ALPHATEST_FAILED 0x00ff0000
10370     struct {
10371         D3DCMPFUNC  func;
10372         DWORD       color_less;
10373         DWORD       color_equal;
10374         DWORD       color_greater;
10375     } testdata[] = {
10376         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10377         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10378         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10379         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10380         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10381         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10382         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10383         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10384     };
10385     unsigned int i, j;
10386     HRESULT hr;
10387     DWORD color;
10388     struct vertex quad[] = {
10389         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10390         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10391         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10392         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10393     };
10394     D3DCAPS9 caps;
10395
10396     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10397     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10398     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10399     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10400
10401     for(j = 0; j < 2; j++) {
10402         if(j == 1) {
10403             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10404              * the alpha test either for performance reasons(floating point RTs) or to work
10405              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10406              * codepath for ffp and shader in this case, and the test should cover both
10407              */
10408             IDirect3DPixelShader9 *ps;
10409             DWORD shader_code[] = {
10410                 0xffff0101,                                 /* ps_1_1           */
10411                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10412                 0x0000ffff                                  /* end              */
10413             };
10414             memset(&caps, 0, sizeof(caps));
10415             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10416             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10417             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10418                 break;
10419             }
10420
10421             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10422             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10423             IDirect3DDevice9_SetPixelShader(device, ps);
10424             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10425             IDirect3DPixelShader9_Release(ps);
10426         }
10427
10428         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10429             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10430             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10431
10432             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10433             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10434             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10435             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10436             hr = IDirect3DDevice9_BeginScene(device);
10437             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10438             if(SUCCEEDED(hr)) {
10439                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10440                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10441                 hr = IDirect3DDevice9_EndScene(device);
10442                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10443             }
10444             color = getPixelColor(device, 320, 240);
10445             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10446             color, testdata[i].color_less, testdata[i].func);
10447             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10448             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10449
10450             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10451             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10452             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10453             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10454             hr = IDirect3DDevice9_BeginScene(device);
10455             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10456             if(SUCCEEDED(hr)) {
10457                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10458                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10459                 hr = IDirect3DDevice9_EndScene(device);
10460                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10461             }
10462             color = getPixelColor(device, 320, 240);
10463             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10464             color, testdata[i].color_equal, testdata[i].func);
10465             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10466             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10467
10468             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10469             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10470             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10471             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10472             hr = IDirect3DDevice9_BeginScene(device);
10473             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10474             if(SUCCEEDED(hr)) {
10475                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10476                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10477                 hr = IDirect3DDevice9_EndScene(device);
10478                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10479             }
10480             color = getPixelColor(device, 320, 240);
10481             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10482             color, testdata[i].color_greater, testdata[i].func);
10483             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10484             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10485         }
10486     }
10487
10488     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10489     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10490     IDirect3DDevice9_SetPixelShader(device, NULL);
10491     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10492 }
10493
10494 static void sincos_test(IDirect3DDevice9 *device) {
10495     const DWORD sin_shader_code[] = {
10496         0xfffe0200,                                                                 /* vs_2_0                       */
10497         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10498         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10499         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10500         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10501         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10502         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10503         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10504         0x0000ffff                                                                  /* end                          */
10505     };
10506     const DWORD cos_shader_code[] = {
10507         0xfffe0200,                                                                 /* vs_2_0                       */
10508         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10509         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10510         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10511         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10512         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10513         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10514         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10515         0x0000ffff                                                                  /* end                          */
10516     };
10517     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10518     HRESULT hr;
10519     struct {
10520         float x, y, z;
10521     } data[1280];
10522     unsigned int i;
10523     float sincosc1[4] = {D3DSINCOSCONST1};
10524     float sincosc2[4] = {D3DSINCOSCONST2};
10525
10526     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10527     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10528
10529     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10530     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10531     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10532     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10533     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10534     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10535     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10536     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10537     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10538     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10539
10540     /* Generate a point from -1 to 1 every 0.5 pixels */
10541     for(i = 0; i < 1280; i++) {
10542         data[i].x = (-640.0 + i) / 640.0;
10543         data[i].y = 0.0;
10544         data[i].z = 0.1;
10545     }
10546
10547     hr = IDirect3DDevice9_BeginScene(device);
10548     if(SUCCEEDED(hr)) {
10549         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10550         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10551         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10552         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10553
10554         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10555         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10556         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10557         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10558
10559         hr = IDirect3DDevice9_EndScene(device);
10560         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10561     }
10562     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10563     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10564     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10565
10566     IDirect3DDevice9_SetVertexShader(device, NULL);
10567     IDirect3DVertexShader9_Release(sin_shader);
10568     IDirect3DVertexShader9_Release(cos_shader);
10569 }
10570
10571 static void loop_index_test(IDirect3DDevice9 *device) {
10572     const DWORD shader_code[] = {
10573         0xfffe0200,                                                 /* vs_2_0                   */
10574         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10575         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10576         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10577         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10578         0x0000001d,                                                 /* endloop                  */
10579         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10580         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10581         0x0000ffff                                                  /* END                      */
10582     };
10583     IDirect3DVertexShader9 *shader;
10584     HRESULT hr;
10585     DWORD color;
10586     const float quad[] = {
10587         -1.0,   -1.0,   0.1,
10588          1.0,   -1.0,   0.1,
10589         -1.0,    1.0,   0.1,
10590          1.0,    1.0,   0.1
10591     };
10592     const float zero[4] = {0, 0, 0, 0};
10593     const float one[4] = {1, 1, 1, 1};
10594     int i0[4] = {2, 10, -3, 0};
10595     float values[4];
10596
10597     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10598     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10599     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10600     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10601     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10602     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10603     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10604     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10605
10606     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10607     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10608     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10609     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10610     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10611     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10612     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10613     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10614     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10615     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10616     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10617     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10618     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10619     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10620     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10621     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10622     values[0] = 1.0;
10623     values[1] = 1.0;
10624     values[2] = 0.0;
10625     values[3] = 0.0;
10626     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10627     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10628     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10629     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10630     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10631     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10632     values[0] = -1.0;
10633     values[1] = 0.0;
10634     values[2] = 0.0;
10635     values[3] = 0.0;
10636     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10637     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10638     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10639     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10640     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10641     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10642     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10643     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10644     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10645     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10646
10647     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10648     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10649
10650     hr = IDirect3DDevice9_BeginScene(device);
10651     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10652     if(SUCCEEDED(hr))
10653     {
10654         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10655         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10656         hr = IDirect3DDevice9_EndScene(device);
10657         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10658     }
10659     color = getPixelColor(device, 320, 240);
10660     ok(color_match(color, 0x0000ff00, 1),
10661        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10662     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10663     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10664
10665     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10666     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10667     IDirect3DVertexShader9_Release(shader);
10668 }
10669
10670 static void sgn_test(IDirect3DDevice9 *device) {
10671     const DWORD shader_code[] = {
10672         0xfffe0200,                                                             /* vs_2_0                       */
10673         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10674         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10675         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10676         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10677         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10678         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10679         0x0000ffff                                                              /* end                          */
10680     };
10681     IDirect3DVertexShader9 *shader;
10682     HRESULT hr;
10683     DWORD color;
10684     const float quad[] = {
10685         -1.0,   -1.0,   0.1,
10686          1.0,   -1.0,   0.1,
10687         -1.0,    1.0,   0.1,
10688          1.0,    1.0,   0.1
10689     };
10690
10691     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10692     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10693     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10694     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10695     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10696     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10697     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10698     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10699
10700     hr = IDirect3DDevice9_BeginScene(device);
10701     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10702     if(SUCCEEDED(hr))
10703     {
10704         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10705         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10706         hr = IDirect3DDevice9_EndScene(device);
10707         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10708     }
10709     color = getPixelColor(device, 320, 240);
10710     ok(color_match(color, 0x008000ff, 1),
10711        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10712     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10713     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10714
10715     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10716     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10717     IDirect3DVertexShader9_Release(shader);
10718 }
10719
10720 static void viewport_test(IDirect3DDevice9 *device) {
10721     HRESULT hr;
10722     DWORD color;
10723     D3DVIEWPORT9 vp, old_vp;
10724     BOOL draw_failed = TRUE;
10725     const float quad[] =
10726     {
10727         -0.5,   -0.5,   0.1,
10728          0.5,   -0.5,   0.1,
10729         -0.5,    0.5,   0.1,
10730          0.5,    0.5,   0.1
10731     };
10732
10733     memset(&old_vp, 0, sizeof(old_vp));
10734     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10735     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10736
10737     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10738     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10739
10740     /* Test a viewport with Width and Height bigger than the surface dimensions
10741      *
10742      * TODO: Test Width < surface.width, but X + Width > surface.width
10743      * TODO: Test Width < surface.width, what happens with the height?
10744      *
10745      * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10746      * and Height fields bigger than the framebuffer. However, it later refuses
10747      * to draw.
10748      */
10749     memset(&vp, 0, sizeof(vp));
10750     vp.X = 0;
10751     vp.Y = 0;
10752     vp.Width = 10000;
10753     vp.Height = 10000;
10754     vp.MinZ = 0.0;
10755     vp.MaxZ = 0.0;
10756     hr = IDirect3DDevice9_SetViewport(device, &vp);
10757     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10758
10759     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10760     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10761     hr = IDirect3DDevice9_BeginScene(device);
10762     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10763     if(SUCCEEDED(hr))
10764     {
10765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10766         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10767         draw_failed = FAILED(hr);
10768         hr = IDirect3DDevice9_EndScene(device);
10769         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10770     }
10771
10772     if(!draw_failed)
10773     {
10774         color = getPixelColor(device, 158, 118);
10775         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10776         color = getPixelColor(device, 162, 118);
10777         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10778         color = getPixelColor(device, 158, 122);
10779         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10780         color = getPixelColor(device, 162, 122);
10781         ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10782
10783         color = getPixelColor(device, 478, 358);
10784         ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10785         color = getPixelColor(device, 482, 358);
10786         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10787         color = getPixelColor(device, 478, 362);
10788         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10789         color = getPixelColor(device, 482, 362);
10790         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10791     }
10792
10793     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10794     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10795
10796     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10797     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10798 }
10799
10800 /* This test tests depth clamping / clipping behaviour:
10801  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10802  *   minimum/maximum z value.
10803  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10804  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10805  *   - Pretransformed vertices behave the same as regular vertices.
10806  */
10807 static void depth_clamp_test(IDirect3DDevice9 *device)
10808 {
10809     const struct tvertex quad1[] =
10810     {
10811         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10812         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10813         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10814         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10815     };
10816     const struct tvertex quad2[] =
10817     {
10818         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10819         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10820         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10821         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10822     };
10823     const struct vertex quad3[] =
10824     {
10825         {-0.65, 0.55,  5.0f,      0xffffffff},
10826         {-0.35, 0.55,  5.0f,      0xffffffff},
10827         {-0.65, 0.15,  5.0f,      0xffffffff},
10828         {-0.35, 0.15,  5.0f,      0xffffffff},
10829     };
10830     const struct vertex quad4[] =
10831     {
10832         {-0.87, 0.83, 10.0f,      0xffffffff},
10833         {-0.65, 0.83, 10.0f,      0xffffffff},
10834         {-0.87, 0.55, 10.0f,      0xffffffff},
10835         {-0.65, 0.55, 10.0f,      0xffffffff},
10836     };
10837     const struct vertex quad5[] =
10838     {
10839         { -0.5,  0.5, 10.0f,      0xff14f914},
10840         {  0.5,  0.5, 10.0f,      0xff14f914},
10841         { -0.5, -0.5, 10.0f,      0xff14f914},
10842         {  0.5, -0.5, 10.0f,      0xff14f914},
10843     };
10844     const struct tvertex quad6[] =
10845     {
10846         {    0,  120, 10.0f, 1.0, 0xfff91414},
10847         {  640,  120, 10.0f, 1.0, 0xfff91414},
10848         {    0,  180, 10.0f, 1.0, 0xfff91414},
10849         {  640,  180, 10.0f, 1.0, 0xfff91414},
10850     };
10851
10852     D3DVIEWPORT9 vp;
10853     D3DCOLOR color;
10854     HRESULT hr;
10855
10856     vp.X = 0;
10857     vp.Y = 0;
10858     vp.Width = 640;
10859     vp.Height = 480;
10860     vp.MinZ = 0.0;
10861     vp.MaxZ = 7.5;
10862
10863     hr = IDirect3DDevice9_SetViewport(device, &vp);
10864     if(FAILED(hr))
10865     {
10866         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10867          * the tests because the 7.5 is just intended to show that it doesn't have
10868          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10869          * viewport and continue.
10870          */
10871         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10872         vp.MaxZ = 1.0;
10873         hr = IDirect3DDevice9_SetViewport(device, &vp);
10874     }
10875     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10876
10877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10878     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10879
10880     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10881     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10882     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10883     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10884     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10885     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10886     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10887     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10888
10889     hr = IDirect3DDevice9_BeginScene(device);
10890     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10891
10892     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10893     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10894
10895     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10896     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10897     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10898     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10899
10900     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10901     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10902
10903     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10904     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10905     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10906     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10907
10908     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10909     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10910
10911     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10912     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10913
10914     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10915     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10916
10917     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10918     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10919
10920     hr = IDirect3DDevice9_EndScene(device);
10921     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10922
10923     color = getPixelColor(device, 75, 75);
10924     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10925     color = getPixelColor(device, 150, 150);
10926     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10927     color = getPixelColor(device, 320, 240);
10928     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10929     color = getPixelColor(device, 320, 330);
10930     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10931     color = getPixelColor(device, 320, 330);
10932     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10933
10934     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10935     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10936
10937     vp.MinZ = 0.0;
10938     vp.MaxZ = 1.0;
10939     hr = IDirect3DDevice9_SetViewport(device, &vp);
10940     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10941 }
10942
10943 static void depth_buffer_test(IDirect3DDevice9 *device)
10944 {
10945     static const struct vertex quad1[] =
10946     {
10947         { -1.0,  1.0, 0.33f, 0xff00ff00},
10948         {  1.0,  1.0, 0.33f, 0xff00ff00},
10949         { -1.0, -1.0, 0.33f, 0xff00ff00},
10950         {  1.0, -1.0, 0.33f, 0xff00ff00},
10951     };
10952     static const struct vertex quad2[] =
10953     {
10954         { -1.0,  1.0, 0.50f, 0xffff00ff},
10955         {  1.0,  1.0, 0.50f, 0xffff00ff},
10956         { -1.0, -1.0, 0.50f, 0xffff00ff},
10957         {  1.0, -1.0, 0.50f, 0xffff00ff},
10958     };
10959     static const struct vertex quad3[] =
10960     {
10961         { -1.0,  1.0, 0.66f, 0xffff0000},
10962         {  1.0,  1.0, 0.66f, 0xffff0000},
10963         { -1.0, -1.0, 0.66f, 0xffff0000},
10964         {  1.0, -1.0, 0.66f, 0xffff0000},
10965     };
10966     static const DWORD expected_colors[4][4] =
10967     {
10968         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10969         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10970         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10971         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10972     };
10973
10974     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10975     unsigned int i, j;
10976     D3DVIEWPORT9 vp;
10977     D3DCOLOR color;
10978     HRESULT hr;
10979
10980     vp.X = 0;
10981     vp.Y = 0;
10982     vp.Width = 640;
10983     vp.Height = 480;
10984     vp.MinZ = 0.0;
10985     vp.MaxZ = 1.0;
10986
10987     hr = IDirect3DDevice9_SetViewport(device, &vp);
10988     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10989
10990     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10991     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10993     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10994     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10995     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10997     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10998     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10999     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11000
11001     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11002     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11003     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11004             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11005     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11006     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11007             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11008     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11009     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11010             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11011     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11012
11013     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11014     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11015     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11016     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11017
11018     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11019     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11020     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11021     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11022
11023     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11024     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11025     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11026     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11027
11028     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11029     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11030     hr = IDirect3DDevice9_BeginScene(device);
11031     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11032     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11033     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11034     hr = IDirect3DDevice9_EndScene(device);
11035     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11036
11037     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11038     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11039     IDirect3DSurface9_Release(backbuffer);
11040     IDirect3DSurface9_Release(rt3);
11041     IDirect3DSurface9_Release(rt2);
11042     IDirect3DSurface9_Release(rt1);
11043
11044     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11045     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11046
11047     hr = IDirect3DDevice9_BeginScene(device);
11048     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11049     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11050     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11051     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11052     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11053     hr = IDirect3DDevice9_EndScene(device);
11054     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11055
11056     for (i = 0; i < 4; ++i)
11057     {
11058         for (j = 0; j < 4; ++j)
11059         {
11060             unsigned int x = 80 * ((2 * j) + 1);
11061             unsigned int y = 60 * ((2 * i) + 1);
11062             color = getPixelColor(device, x, y);
11063             ok(color_match(color, expected_colors[i][j], 0),
11064                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11065         }
11066     }
11067
11068     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11069     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11070 }
11071
11072 static void shadow_test(IDirect3DDevice9 *device)
11073 {
11074     static const DWORD ps_code[] =
11075     {
11076         0xffff0200,                                                             /* ps_2_0                       */
11077         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11078         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11079         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11080         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11081         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11082         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11083         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11084         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11085         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11086         0x0000ffff,                                                             /* end                          */
11087     };
11088     struct
11089     {
11090         D3DFORMAT format;
11091         const char *name;
11092     }
11093     formats[] =
11094     {
11095         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11096         {D3DFMT_D32,            "D3DFMT_D32"},
11097         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11098         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11099         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11100         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11101         {D3DFMT_D16,            "D3DFMT_D16"},
11102         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11103         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11104     };
11105     struct
11106     {
11107         float x, y, z;
11108         float s, t, p, q;
11109     }
11110     quad[] =
11111     {
11112         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11113         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11114         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11115         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11116     };
11117     struct
11118     {
11119         UINT x, y;
11120         D3DCOLOR color;
11121     }
11122     expected_colors[] =
11123     {
11124         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11125         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11126         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11127         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11128         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11129         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11130         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11131         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11132     };
11133
11134     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11135     IDirect3DPixelShader9 *ps;
11136     IDirect3D9 *d3d9;
11137     D3DCAPS9 caps;
11138     HRESULT hr;
11139     UINT i;
11140
11141     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11142     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11143     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11144     {
11145         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11146         return;
11147     }
11148
11149     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11150     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11151     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11152     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11153     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11154     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11155
11156     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11157             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11158     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11159     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11160     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11161
11162     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11163     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11164     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11165     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11166     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11167     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11168     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11169     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11170     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11171     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11172
11173     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11174     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11175     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11176     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11177     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11178     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11179     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11180     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11181     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11182     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11183
11184     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11185     {
11186         D3DFORMAT format = formats[i].format;
11187         IDirect3DTexture9 *texture;
11188         IDirect3DSurface9 *ds;
11189         unsigned int j;
11190
11191         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11192                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11193         if (FAILED(hr)) continue;
11194
11195         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11196                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11197         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11198
11199         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11200         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11201
11202         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11203         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11204
11205         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11206         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11207
11208         IDirect3DDevice9_SetPixelShader(device, NULL);
11209         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11210
11211         /* Setup the depth/stencil surface. */
11212         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11213         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11214
11215         hr = IDirect3DDevice9_BeginScene(device);
11216         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11217         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11218         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11219         hr = IDirect3DDevice9_EndScene(device);
11220         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11221
11222         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11223         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11224         IDirect3DSurface9_Release(ds);
11225
11226         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11227         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11228
11229         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11230         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11231
11232         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11233         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11234
11235         /* Do the actual shadow mapping. */
11236         hr = IDirect3DDevice9_BeginScene(device);
11237         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11238         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11239         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11240         hr = IDirect3DDevice9_EndScene(device);
11241         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11242
11243         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11244         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11245         IDirect3DTexture9_Release(texture);
11246
11247         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11248         {
11249             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11250             ok(color_match(color, expected_colors[j].color, 0),
11251                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11252                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11253                     formats[i].name, color);
11254         }
11255
11256         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11257         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11258     }
11259
11260     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11261     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11262     IDirect3DPixelShader9_Release(ps);
11263
11264     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11265     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11266     IDirect3DSurface9_Release(original_ds);
11267
11268     IDirect3DSurface9_Release(original_rt);
11269     IDirect3DSurface9_Release(rt);
11270
11271     IDirect3D9_Release(d3d9);
11272 }
11273
11274 START_TEST(visual)
11275 {
11276     IDirect3DDevice9 *device_ptr;
11277     D3DCAPS9 caps;
11278     HRESULT hr;
11279     DWORD color;
11280
11281     d3d9_handle = LoadLibraryA("d3d9.dll");
11282     if (!d3d9_handle)
11283     {
11284         skip("Could not load d3d9.dll\n");
11285         return;
11286     }
11287
11288     device_ptr = init_d3d9();
11289     if (!device_ptr)
11290     {
11291         skip("Creating the device failed\n");
11292         return;
11293     }
11294
11295     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11296
11297     /* Check for the reliability of the returned data */
11298     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11299     if(FAILED(hr))
11300     {
11301         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11302         goto cleanup;
11303     }
11304
11305     color = getPixelColor(device_ptr, 1, 1);
11306     if(color !=0x00ff0000)
11307     {
11308         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11309         goto cleanup;
11310     }
11311     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11312
11313     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11314     if(FAILED(hr))
11315     {
11316         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11317         goto cleanup;
11318     }
11319
11320     color = getPixelColor(device_ptr, 639, 479);
11321     if(color != 0x0000ddee)
11322     {
11323         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11324         goto cleanup;
11325     }
11326     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11327
11328     /* Now execute the real tests */
11329     depth_clamp_test(device_ptr);
11330     stretchrect_test(device_ptr);
11331     lighting_test(device_ptr);
11332     clear_test(device_ptr);
11333     color_fill_test(device_ptr);
11334     fog_test(device_ptr);
11335     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11336     {
11337         test_cube_wrap(device_ptr);
11338     } else {
11339         skip("No cube texture support\n");
11340     }
11341     z_range_test(device_ptr);
11342     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11343     {
11344         maxmip_test(device_ptr);
11345     }
11346     else
11347     {
11348         skip("No mipmap support\n");
11349     }
11350     offscreen_test(device_ptr);
11351     alpha_test(device_ptr);
11352     shademode_test(device_ptr);
11353     srgbtexture_test(device_ptr);
11354     release_buffer_test(device_ptr);
11355     float_texture_test(device_ptr);
11356     g16r16_texture_test(device_ptr);
11357     pixelshader_blending_test(device_ptr);
11358     texture_transform_flags_test(device_ptr);
11359     autogen_mipmap_test(device_ptr);
11360     fixed_function_decl_test(device_ptr);
11361     conditional_np2_repeat_test(device_ptr);
11362     fixed_function_bumpmap_test(device_ptr);
11363     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11364         stencil_cull_test(device_ptr);
11365     } else {
11366         skip("No two sided stencil support\n");
11367     }
11368     pointsize_test(device_ptr);
11369     tssargtemp_test(device_ptr);
11370     np2_stretch_rect_test(device_ptr);
11371     yuv_color_test(device_ptr);
11372     zwriteenable_test(device_ptr);
11373     alphatest_test(device_ptr);
11374     viewport_test(device_ptr);
11375
11376     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11377     {
11378         test_constant_clamp_vs(device_ptr);
11379         test_compare_instructions(device_ptr);
11380     }
11381     else skip("No vs_1_1 support\n");
11382
11383     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11384     {
11385         test_mova(device_ptr);
11386         loop_index_test(device_ptr);
11387         sincos_test(device_ptr);
11388         sgn_test(device_ptr);
11389         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11390             test_vshader_input(device_ptr);
11391             test_vshader_float16(device_ptr);
11392             stream_test(device_ptr);
11393         } else {
11394             skip("No vs_3_0 support\n");
11395         }
11396     }
11397     else skip("No vs_2_0 support\n");
11398
11399     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11400     {
11401         fog_with_shader_test(device_ptr);
11402     }
11403     else skip("No vs_1_1 and ps_1_1 support\n");
11404
11405     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11406     {
11407         texbem_test(device_ptr);
11408         texdepth_test(device_ptr);
11409         texkill_test(device_ptr);
11410         x8l8v8u8_test(device_ptr);
11411         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11412             constant_clamp_ps_test(device_ptr);
11413             cnd_test(device_ptr);
11414             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11415                 dp2add_ps_test(device_ptr);
11416                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11417                     nested_loop_test(device_ptr);
11418                     fixed_function_varying_test(device_ptr);
11419                     vFace_register_test(device_ptr);
11420                     vpos_register_test(device_ptr);
11421                     multiple_rendertargets_test(device_ptr);
11422                     vshader_version_varying_test(device_ptr);
11423                     pshader_version_varying_test(device_ptr);
11424                 } else {
11425                     skip("No ps_3_0 or vs_3_0 support\n");
11426                 }
11427             } else {
11428                 skip("No ps_2_0 support\n");
11429             }
11430         }
11431     }
11432     else skip("No ps_1_1 support\n");
11433
11434     texop_test(device_ptr);
11435     texop_range_test(device_ptr);
11436     alphareplicate_test(device_ptr);
11437     dp3_alpha_test(device_ptr);
11438     depth_buffer_test(device_ptr);
11439     shadow_test(device_ptr);
11440
11441 cleanup:
11442     if(device_ptr) {
11443         D3DPRESENT_PARAMETERS present_parameters;
11444         IDirect3DSwapChain9 *swapchain;
11445         ULONG ref;
11446
11447         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11448         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11449         IDirect3DSwapChain9_Release(swapchain);
11450         ref = IDirect3DDevice9_Release(device_ptr);
11451         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11452         DestroyWindow(present_parameters.hDeviceWindow);
11453     }
11454 }