d3d9/tests: Add missing skip().
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007 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 <dxerr9.h>
34 #include "wine/test.h"
35
36 static HMODULE d3d9_handle = 0;
37
38 static HWND create_window(void)
39 {
40     WNDCLASS wc = {0};
41     HWND ret;
42     wc.lpfnWndProc = &DefWindowProc;
43     wc.lpszClassName = "d3d9_test_wc";
44     RegisterClass(&wc);
45
46     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
47                         WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
48     return ret;
49 }
50
51 /* Locks a given surface and returns the color at (x,y).  It's the caller's
52  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
53 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
54 {
55     DWORD color;
56     HRESULT hr;
57     D3DSURFACE_DESC desc;
58     RECT rectToLock = {x, y, x+1, y+1};
59     D3DLOCKED_RECT lockedRect;
60
61     hr = IDirect3DSurface9_GetDesc(surface, &desc);
62     if(FAILED(hr))  /* This is not a test */
63     {
64         trace("Can't get the surface description, hr=%s\n", DXGetErrorString9(hr));
65         return 0xdeadbeef;
66     }
67
68     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
69     if(FAILED(hr))  /* This is not a test */
70     {
71         trace("Can't lock the surface, hr=%s\n", DXGetErrorString9(hr));
72         return 0xdeadbeef;
73     }
74     switch(desc.Format) {
75         case D3DFMT_A8R8G8B8:
76         {
77             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
78             break;
79         }
80         default:
81             trace("Error: unknown surface format: %d\n", desc.Format);
82             color = 0xdeadbeef;
83             break;
84     }
85     hr = IDirect3DSurface9_UnlockRect(surface);
86     if(FAILED(hr))
87     {
88         trace("Can't unlock the surface, hr=%s\n", DXGetErrorString9(hr));
89     }
90     return color;
91 }
92
93 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
94 {
95     DWORD ret;
96     IDirect3DSurface9 *surf;
97     HRESULT hr;
98     D3DLOCKED_RECT lockedRect;
99     RECT rectToLock = {x, y, x+1, y+1};
100
101     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
102     if(FAILED(hr) || !surf )  /* This is not a test */
103     {
104         trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
105         return 0xdeadbeef;
106     }
107
108     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
109     if(FAILED(hr))
110     {
111         trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
112         ret = 0xdeadbeed;
113         goto out;
114     }
115
116     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
117     if(FAILED(hr))
118     {
119         trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
120         ret = 0xdeadbeec;
121         goto out;
122     }
123
124     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
125      * really important for these tests
126      */
127     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
128     hr = IDirect3DSurface9_UnlockRect(surf);
129     if(FAILED(hr))
130     {
131         trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
132     }
133
134 out:
135     if(surf) IDirect3DSurface9_Release(surf);
136     return ret;
137 }
138
139 static IDirect3DDevice9 *init_d3d9(void)
140 {
141     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
142     IDirect3D9 *d3d9_ptr = 0;
143     IDirect3DDevice9 *device_ptr = 0;
144     D3DPRESENT_PARAMETERS present_parameters;
145     HRESULT hr;
146     D3DADAPTER_IDENTIFIER9 identifier;
147
148     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
149     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
150     if (!d3d9_create) return NULL;
151
152     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
153     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
154     if (!d3d9_ptr) return NULL;
155
156     ZeroMemory(&present_parameters, sizeof(present_parameters));
157     present_parameters.Windowed = FALSE;
158     present_parameters.hDeviceWindow = create_window();
159     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
160     present_parameters.BackBufferWidth = 640;
161     present_parameters.BackBufferHeight = 480;
162     present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
163     present_parameters.EnableAutoDepthStencil = TRUE;
164     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
165
166     memset(&identifier, 0, sizeof(identifier));
167     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
168     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
169     trace("Driver string: \"%s\"\n", identifier.Driver);
170     trace("Description string: \"%s\"\n", identifier.Description);
171     trace("Device name string: \"%s\"\n", identifier.DeviceName);
172     trace("Driver version %d.%d.%d.%d\n",
173           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
174           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
175
176     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
177     if(FAILED(hr)) {
178         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
179         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
180         if(FAILED(hr)) {
181             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
182         }
183     }
184     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
185
186     return device_ptr;
187 }
188
189 struct vertex
190 {
191     float x, y, z;
192     DWORD diffuse;
193 };
194
195 struct tvertex
196 {
197     float x, y, z, rhw;
198     DWORD diffuse;
199 };
200
201 struct nvertex
202 {
203     float x, y, z;
204     float nx, ny, nz;
205     DWORD diffuse;
206 };
207
208 static void lighting_test(IDirect3DDevice9 *device)
209 {
210     HRESULT hr;
211     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
212     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
213     DWORD color;
214
215     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
216                       0.0f, 1.0f, 0.0f, 0.0f,
217                       0.0f, 0.0f, 1.0f, 0.0f,
218                       0.0f, 0.0f, 0.0f, 1.0f };
219
220     struct vertex unlitquad[] =
221     {
222         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
223         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
224         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
225         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
226     };
227     struct vertex litquad[] =
228     {
229         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
230         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
231         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
232         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
233     };
234     struct nvertex unlitnquad[] =
235     {
236         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
237         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
238         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
239         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
240     };
241     struct nvertex litnquad[] =
242     {
243         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
244         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
245         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
246         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
247     };
248     WORD Indices[] = {0, 1, 2, 2, 3, 0};
249
250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
252
253     /* Setup some states that may cause issues */
254     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
255     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
256     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
257     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
258     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
259     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
260     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
261     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
262     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
263     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
264     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
265     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
266     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
267     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
274     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
275     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
276     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
277     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
278
279     hr = IDirect3DDevice9_SetFVF(device, fvf);
280     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
281
282     hr = IDirect3DDevice9_BeginScene(device);
283     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
284     if(hr == D3D_OK)
285     {
286         /* No lights are defined... That means, lit vertices should be entirely black */
287         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
288         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
289         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
290                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
291         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
292
293         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
294         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
295         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
296                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
297         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
298
299         hr = IDirect3DDevice9_SetFVF(device, nfvf);
300         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
301
302         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
303         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
304         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
305                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
306         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
307
308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
310         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
311                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
312         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
313
314         IDirect3DDevice9_EndScene(device);
315         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
316     }
317
318     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
319
320     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
321     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
322     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
323     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
324     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
325     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
326     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
327     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
328
329     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
330     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
331 }
332
333 static void clear_test(IDirect3DDevice9 *device)
334 {
335     /* Tests the correctness of clearing parameters */
336     HRESULT hr;
337     D3DRECT rect[2];
338     D3DRECT rect_negneg;
339     DWORD color;
340     D3DVIEWPORT9 old_vp, vp;
341     RECT scissor;
342     DWORD oldColorWrite;
343     BOOL invalid_clear_failed = FALSE;
344
345     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
346     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
347
348     /* Positive x, negative y */
349     rect[0].x1 = 0;
350     rect[0].y1 = 480;
351     rect[0].x2 = 320;
352     rect[0].y2 = 240;
353
354     /* Positive x, positive y */
355     rect[1].x1 = 0;
356     rect[1].y1 = 0;
357     rect[1].x2 = 320;
358     rect[1].y2 = 240;
359     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
360      * returns D3D_OK, but ignores the rectangle silently
361      */
362     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
363     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
364     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
365
366     /* negative x, negative y */
367     rect_negneg.x1 = 640;
368     rect_negneg.y1 = 240;
369     rect_negneg.x2 = 320;
370     rect_negneg.y2 = 0;
371     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
372     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
373     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
374
375     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
376
377     color = getPixelColor(device, 160, 360); /* lower left quad */
378     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
379     color = getPixelColor(device, 160, 120); /* upper left quad */
380     if(invalid_clear_failed) {
381         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
382         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
383     } else {
384         /* If the negative rectangle was dropped silently, the correct ones are cleared */
385         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
386     }
387     color = getPixelColor(device, 480, 360); /* lower right quad  */
388     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
389     color = getPixelColor(device, 480, 120); /* upper right quad */
390     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
391
392     /* Test how the viewport affects clears */
393     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
394     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
395     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
396     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
397
398     vp.X = 160;
399     vp.Y = 120;
400     vp.Width = 160;
401     vp.Height = 120;
402     vp.MinZ = 0.0;
403     vp.MaxZ = 1.0;
404     hr = IDirect3DDevice9_SetViewport(device, &vp);
405     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
406     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
407     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
408
409     vp.X = 320;
410     vp.Y = 240;
411     vp.Width = 320;
412     vp.Height = 240;
413     vp.MinZ = 0.0;
414     vp.MaxZ = 1.0;
415     hr = IDirect3DDevice9_SetViewport(device, &vp);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
417     rect[0].x1 = 160;
418     rect[0].y1 = 120;
419     rect[0].x2 = 480;
420     rect[0].y2 = 360;
421     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
422     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
423
424     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
425     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
426
427     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
428     color = getPixelColor(device, 158, 118);
429     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
430     color = getPixelColor(device, 162, 118);
431     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
432     color = getPixelColor(device, 158, 122);
433     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
434     color = getPixelColor(device, 162, 122);
435     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
436
437     color = getPixelColor(device, 318, 238);
438     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
439     color = getPixelColor(device, 322, 238);
440     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
441     color = getPixelColor(device, 318, 242);
442     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
443     color = getPixelColor(device, 322, 242);
444     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
445
446     color = getPixelColor(device, 478, 358);
447     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
448     color = getPixelColor(device, 482, 358);
449     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
450     color = getPixelColor(device, 478, 362);
451     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
452     color = getPixelColor(device, 482, 362);
453     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
454
455     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
456     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
457
458     scissor.left = 160;
459     scissor.right = 480;
460     scissor.top = 120;
461     scissor.bottom = 360;
462     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
463     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
464     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
465     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
466
467     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
468     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
469     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
470     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
471
472     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
473     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
474
475     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
476     color = getPixelColor(device, 158, 118);
477     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
478     color = getPixelColor(device, 162, 118);
479     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
480     color = getPixelColor(device, 158, 122);
481     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
482     color = getPixelColor(device, 162, 122);
483     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
484
485     color = getPixelColor(device, 158, 358);
486     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
487     color = getPixelColor(device, 162, 358);
488     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
489     color = getPixelColor(device, 158, 358);
490     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
491     color = getPixelColor(device, 162, 362);
492     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
493
494     color = getPixelColor(device, 478, 118);
495     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
496     color = getPixelColor(device, 478, 122);
497     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
498     color = getPixelColor(device, 482, 122);
499     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
500     color = getPixelColor(device, 482, 358);
501     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
502
503     color = getPixelColor(device, 478, 358);
504     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
505     color = getPixelColor(device, 478, 362);
506     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
507     color = getPixelColor(device, 482, 358);
508     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
509     color = getPixelColor(device, 482, 362);
510     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
511
512     color = getPixelColor(device, 318, 238);
513     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
514     color = getPixelColor(device, 318, 242);
515     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
516     color = getPixelColor(device, 322, 238);
517     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
518     color = getPixelColor(device, 322, 242);
519     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
520
521     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
522     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
523     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
524     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
525
526     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
527     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
528
529     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
530     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
531
532     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
533
534     /* Colorwriteenable does not affect the clear */
535     color = getPixelColor(device, 320, 240);
536     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
537 }
538
539 typedef struct {
540     float in[4];
541     DWORD out;
542 } test_data_t;
543
544 /*
545  *  c7      mova    ARGB            mov     ARGB
546  * -2.4     -2      0x00ffff00      -3      0x00ff0000
547  * -1.6     -2      0x00ffff00      -2      0x00ffff00
548  * -0.4      0      0x0000ffff      -1      0x0000ff00
549  *  0.4      0      0x0000ffff       0      0x0000ffff
550  *  1.6      2      0x00ff00ff       1      0x000000ff
551  *  2.4      2      0x00ff00ff       2      0x00ff00ff
552  */
553 static void test_mova(IDirect3DDevice9 *device)
554 {
555     static const DWORD mova_test[] = {
556         0xfffe0200,                                                             /* vs_2_0                       */
557         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
558         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
559         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
560         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
561         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
562         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
563         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
564         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
565         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
566         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
567         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
568         0x0000ffff                                                              /* END                          */
569     };
570     static const DWORD mov_test[] = {
571         0xfffe0101,                                                             /* vs_1_1                       */
572         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
573         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
574         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
575         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
576         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
577         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
578         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
579         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
580         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
581         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
582         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
583         0x0000ffff                                                              /* END                          */
584     };
585
586     static const test_data_t test_data[2][6] = {
587         {
588             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
589             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
590             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
591             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
592             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
593             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
594         },
595         {
596             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
597             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
598             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
599             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
600             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
601             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
602         }
603     };
604
605     static const float quad[][3] = {
606         {-1.0f, -1.0f, 0.0f},
607         {-1.0f,  1.0f, 0.0f},
608         { 1.0f, -1.0f, 0.0f},
609         { 1.0f,  1.0f, 0.0f},
610     };
611
612     static const D3DVERTEXELEMENT9 decl_elements[] = {
613         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
614         D3DDECL_END()
615     };
616
617     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
618     IDirect3DVertexShader9 *mova_shader = NULL;
619     IDirect3DVertexShader9 *mov_shader = NULL;
620     HRESULT hr;
621     UINT i, j;
622
623     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
624     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
625     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
626     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
627     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
628     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
629     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
630     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
631
632     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
633     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
634     for(j = 0; j < 2; ++j)
635     {
636         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
637         {
638             DWORD color;
639
640             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
641             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
642
643             hr = IDirect3DDevice9_BeginScene(device);
644             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
645
646             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
647             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
648
649             hr = IDirect3DDevice9_EndScene(device);
650             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
651
652             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
653             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
654
655             color = getPixelColor(device, 320, 240);
656             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
657                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
658
659             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
660             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
661         }
662         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
663         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
664     }
665
666     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
667     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
668
669     IDirect3DVertexDeclaration9_Release(vertex_declaration);
670     IDirect3DVertexShader9_Release(mova_shader);
671     IDirect3DVertexShader9_Release(mov_shader);
672 }
673
674 struct sVertex {
675     float x, y, z;
676     DWORD diffuse;
677     DWORD specular;
678 };
679
680 struct sVertexT {
681     float x, y, z, rhw;
682     DWORD diffuse;
683     DWORD specular;
684 };
685
686 static void fog_test(IDirect3DDevice9 *device)
687 {
688     HRESULT hr;
689     DWORD color;
690     BYTE r, g, b;
691     float start = 0.0f, end = 1.0f;
692     D3DCAPS9 caps;
693     int i;
694
695     /* Gets full z based fog with linear fog, no fog with specular color */
696     struct sVertex unstransformed_1[] = {
697         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
698         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
699         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
700         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
701     };
702     /* Ok, I am too lazy to deal with transform matrices */
703     struct sVertex unstransformed_2[] = {
704         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
705         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
706         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
707         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
708     };
709     /* Untransformed ones. Give them a different diffuse color to make the test look
710      * nicer. It also makes making sure that they are drawn correctly easier.
711      */
712     struct sVertexT transformed_1[] = {
713         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
714         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
715         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
716         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
717     };
718     struct sVertexT transformed_2[] = {
719         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
720         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
721         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
722         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
723     };
724     struct vertex rev_fog_quads[] = {
725        {-1.0,   -1.0,   0.1,    0x000000ff},
726        {-1.0,    0.0,   0.1,    0x000000ff},
727        { 0.0,    0.0,   0.1,    0x000000ff},
728        { 0.0,   -1.0,   0.1,    0x000000ff},
729
730        { 0.0,   -1.0,   0.9,    0x000000ff},
731        { 0.0,    0.0,   0.9,    0x000000ff},
732        { 1.0,    0.0,   0.9,    0x000000ff},
733        { 1.0,   -1.0,   0.9,    0x000000ff},
734
735        { 0.0,    0.0,   0.4,    0x000000ff},
736        { 0.0,    1.0,   0.4,    0x000000ff},
737        { 1.0,    1.0,   0.4,    0x000000ff},
738        { 1.0,    0.0,   0.4,    0x000000ff},
739
740        {-1.0,    0.0,   0.7,    0x000000ff},
741        {-1.0,    1.0,   0.7,    0x000000ff},
742        { 0.0,    1.0,   0.7,    0x000000ff},
743        { 0.0,    0.0,   0.7,    0x000000ff},
744     };
745     WORD Indices[] = {0, 1, 2, 2, 3, 0};
746
747     memset(&caps, 0, sizeof(caps));
748     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
749     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
750     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
751     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
752
753     /* Setup initial states: No lighting, fog on, fog color */
754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
755     ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
757     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
759     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
760
761     /* First test: Both table fog and vertex fog off */
762     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
763     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
764     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
765     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
766
767     /* Start = 0, end = 1. Should be default, but set them */
768     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
769     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
770     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
771     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
772
773     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
774     {
775         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
776         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
777         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
778         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
779                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
780                                                      sizeof(unstransformed_1[0]));
781         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
782
783         /* That makes it use the Z value */
784         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
785         ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
786         /* Untransformed, vertex fog != none (or table fog != none):
787          * Use the Z value as input into the equation
788          */
789         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
790                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
791                                                      sizeof(unstransformed_1[0]));
792         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
793
794         /* transformed verts */
795         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
796         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
797         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
798         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
799                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
800                                                      sizeof(transformed_1[0]));
801         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
802
803         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
804         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
805         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
806          * equation
807          */
808         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
809                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
810                                                      sizeof(transformed_2[0]));
811
812         hr = IDirect3DDevice9_EndScene(device);
813         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
814     }
815     else
816     {
817         ok(FALSE, "BeginScene failed\n");
818     }
819
820     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
821     color = getPixelColor(device, 160, 360);
822     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
823     color = getPixelColor(device, 160, 120);
824     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
825     color = getPixelColor(device, 480, 120);
826     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
827     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
828     {
829         color = getPixelColor(device, 480, 360);
830         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
831     }
832     else
833     {
834         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
835          * The settings above result in no fogging with vertex fog
836          */
837         color = getPixelColor(device, 480, 120);
838         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
839         trace("Info: Table fog not supported by this device\n");
840     }
841
842     /* Now test the special case fogstart == fogend */
843     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
844     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
845
846     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
847     {
848         start = 512;
849         end = 512;
850         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
851         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
852         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
853         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
854
855         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
856         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
857         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
858         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
859         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
860         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
861
862         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
863          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
864          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
865          * The third transformed quad remains unfogged because the fogcoords are read from the specular
866          * color and has fixed fogstart and fogend.
867          */
868         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
869                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
870                 sizeof(unstransformed_1[0]));
871         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
872         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
873                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
874                 sizeof(unstransformed_1[0]));
875         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
876
877         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
878         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
879         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
880         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
881                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
882                 sizeof(transformed_1[0]));
883         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
884
885         hr = IDirect3DDevice9_EndScene(device);
886         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
887     }
888     else
889     {
890         ok(FALSE, "BeginScene failed\n");
891     }
892     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
893     color = getPixelColor(device, 160, 360);
894     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
895     color = getPixelColor(device, 160, 120);
896     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
897     color = getPixelColor(device, 480, 120);
898     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
899
900     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
901      * but without shaders it seems to work everywhere
902      */
903     end = 0.2;
904     start = 0.8;
905     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
906     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
908     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
910     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
911
912     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
913      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
914      * so skip this for now
915      */
916     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
917         const char *mode = (i ? "table" : "vertex");
918         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
919         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
920         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
921         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
922         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
923         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
924         hr = IDirect3DDevice9_BeginScene(device);
925         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
926         if(SUCCEEDED(hr)) {
927             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
928                                 4,  5,  6,  6,  7, 4,
929                                 8,  9, 10, 10, 11, 8,
930                             12, 13, 14, 14, 15, 12};
931
932             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
933                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
934                     sizeof(rev_fog_quads[0]));
935
936             hr = IDirect3DDevice9_EndScene(device);
937             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
938         }
939         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
940         color = getPixelColor(device, 160, 360);
941         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
942
943         color = getPixelColor(device, 160, 120);
944         r = (color & 0x00ff0000) >> 16;
945         g = (color & 0x0000ff00) >>  8;
946         b = (color & 0x000000ff);
947         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
948            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
949
950         color = getPixelColor(device, 480, 120);
951         r = (color & 0x00ff0000) >> 16;
952         g = (color & 0x0000ff00) >>  8;
953         b = (color & 0x000000ff);
954         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
955            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
956
957         color = getPixelColor(device, 480, 360);
958         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
959
960         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
961             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
962             break;
963         }
964     }
965     /* Turn off the fog master switch to avoid confusing other tests */
966     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
967     ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
968     start = 0.0;
969     end = 1.0;
970     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
971     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
972     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
973     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
974     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
975     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
976     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
977     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
978 }
979
980 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
981  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
982  * regardless of the actual addressing mode set. */
983 static void test_cube_wrap(IDirect3DDevice9 *device)
984 {
985     static const float quad[][6] = {
986         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
987         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
988         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
989         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
990     };
991
992     static const D3DVERTEXELEMENT9 decl_elements[] = {
993         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
994         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
995         D3DDECL_END()
996     };
997
998     static const struct {
999         D3DTEXTUREADDRESS mode;
1000         const char *name;
1001     } address_modes[] = {
1002         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1003         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1004         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1005         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1006         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1007     };
1008
1009     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1010     IDirect3DCubeTexture9 *texture = NULL;
1011     IDirect3DSurface9 *surface = NULL;
1012     D3DLOCKED_RECT locked_rect;
1013     HRESULT hr;
1014     UINT x;
1015     INT y, face;
1016
1017     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1018     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1019     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1020     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1021
1022     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1023             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1024     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1025
1026     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1027     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1028
1029     for (y = 0; y < 128; ++y)
1030     {
1031         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1032         for (x = 0; x < 64; ++x)
1033         {
1034             *ptr++ = 0xffff0000;
1035         }
1036         for (x = 64; x < 128; ++x)
1037         {
1038             *ptr++ = 0xff0000ff;
1039         }
1040     }
1041
1042     hr = IDirect3DSurface9_UnlockRect(surface);
1043     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1044
1045     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1046             D3DPOOL_DEFAULT, &texture, NULL);
1047     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1048
1049     /* Create cube faces */
1050     for (face = 0; face < 6; ++face)
1051     {
1052         IDirect3DSurface9 *face_surface = NULL;
1053
1054         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1055         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1056
1057         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1058         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1059
1060         IDirect3DSurface9_Release(face_surface);
1061     }
1062
1063     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1064     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1065
1066     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1067     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1068     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1069     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1070     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1071     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1072
1073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1074     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1075
1076     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1077     {
1078         DWORD color;
1079
1080         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1081         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1082         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1083         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1084
1085         hr = IDirect3DDevice9_BeginScene(device);
1086         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1087
1088         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1089         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1090
1091         hr = IDirect3DDevice9_EndScene(device);
1092         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1093
1094         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1095         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1096
1097         /* Due to the nature of this test, we sample essentially at the edge
1098          * between two faces. Because of this it's undefined from which face
1099          * the driver will sample. Fortunately that's not important for this
1100          * test, since all we care about is that it doesn't sample from the
1101          * other side of the surface or from the border. */
1102         color = getPixelColor(device, 320, 240);
1103         ok(color == 0x00ff0000 || color == 0x000000ff,
1104                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1105                 color, address_modes[x].name);
1106
1107         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1108         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1109     }
1110
1111     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1112     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1113
1114     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1115     IDirect3DCubeTexture9_Release(texture);
1116     IDirect3DSurface9_Release(surface);
1117 }
1118
1119 static void offscreen_test(IDirect3DDevice9 *device)
1120 {
1121     HRESULT hr;
1122     IDirect3DTexture9 *offscreenTexture = NULL;
1123     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1124     DWORD color;
1125
1126     static const float quad[][5] = {
1127         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1128         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1129         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1130         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1131     };
1132
1133     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1134     ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1135
1136     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1137     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1138     if(!offscreenTexture) {
1139         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1140         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1141         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1142         if(!offscreenTexture) {
1143             skip("Cannot create an offscreen render target\n");
1144             goto out;
1145         }
1146     }
1147
1148     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1149     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1150     if(!backbuffer) {
1151         goto out;
1152     }
1153
1154     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1155     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1156     if(!offscreen) {
1157         goto out;
1158     }
1159
1160     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1161     ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1162
1163     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1164     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1165     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1166     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1167     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1168     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1169     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1170     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1171     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1172     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1173
1174     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1175         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1176         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1177         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1178         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1179
1180         /* Draw without textures - Should result in a white quad */
1181         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1182         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1183
1184         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1185         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1186         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1187         ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1188
1189         /* This time with the texture */
1190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1191         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1192
1193         IDirect3DDevice9_EndScene(device);
1194     }
1195
1196     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1197
1198     /* Center quad - should be white */
1199     color = getPixelColor(device, 320, 240);
1200     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1201     /* Some quad in the cleared part of the texture */
1202     color = getPixelColor(device, 170, 240);
1203     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1204     /* Part of the originally cleared back buffer */
1205     color = getPixelColor(device, 10, 10);
1206     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1207     if(0) {
1208         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1209          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1210          * the offscreen rendering mode this test would succeed or fail
1211          */
1212         color = getPixelColor(device, 10, 470);
1213         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1214     }
1215
1216 out:
1217     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1218
1219     /* restore things */
1220     if(backbuffer) {
1221         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1222         IDirect3DSurface9_Release(backbuffer);
1223     }
1224     if(offscreenTexture) {
1225         IDirect3DTexture9_Release(offscreenTexture);
1226     }
1227     if(offscreen) {
1228         IDirect3DSurface9_Release(offscreen);
1229     }
1230 }
1231
1232 /* This test tests fog in combination with shaders.
1233  * What's tested: linear fog (vertex and table) with pixel shader
1234  *                linear table fog with non foggy vertex shader
1235  *                vertex fog with foggy vertex shader
1236  * What's not tested: non linear fog with shader
1237  *                    table fog with foggy vertex shader
1238  */
1239 static void fog_with_shader_test(IDirect3DDevice9 *device)
1240 {
1241     HRESULT hr;
1242     DWORD color;
1243     union {
1244         float f;
1245         DWORD i;
1246     } start, end;
1247     unsigned int i, j;
1248
1249     /* basic vertex shader without fog computation ("non foggy") */
1250     static const DWORD vertex_shader_code1[] = {
1251         0xfffe0101,                                                             /* vs_1_1                       */
1252         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1253         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1254         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1255         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1256         0x0000ffff
1257     };
1258     /* basic vertex shader with reversed fog computation ("foggy") */
1259     static const DWORD vertex_shader_code2[] = {
1260         0xfffe0101,                                                             /* vs_1_1                        */
1261         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1262         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1263         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1264         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1265         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1266         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1267         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1268         0x0000ffff
1269     };
1270     /* basic pixel shader */
1271     static const DWORD pixel_shader_code[] = {
1272         0xffff0101,                                                             /* ps_1_1     */
1273         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1274         0x0000ffff
1275     };
1276
1277     static struct vertex quad[] = {
1278         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1279         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1280         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1281         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1282     };
1283
1284     static const D3DVERTEXELEMENT9 decl_elements[] = {
1285         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1286         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1287         D3DDECL_END()
1288     };
1289
1290     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1291     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1292     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1293
1294     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1295     static const struct test_data_t {
1296         int vshader;
1297         int pshader;
1298         D3DFOGMODE vfog;
1299         D3DFOGMODE tfog;
1300         unsigned int color[11];
1301     } test_data[] = {
1302         /* only pixel shader: */
1303         {0, 1, 0, 3,
1304         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1305         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1306         {0, 1, 1, 3,
1307         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1308         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1309         {0, 1, 2, 3,
1310         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1311         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1312         {0, 1, 3, 0,
1313         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1314         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1315         {0, 1, 3, 3,
1316         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1317         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1318
1319         /* vertex shader */
1320         {1, 0, 0, 0,
1321         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1322          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1323         {1, 0, 0, 3,
1324         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1325         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1326         {1, 0, 1, 3,
1327         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1328         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1329
1330         {1, 0, 2, 3,
1331         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1332         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1333         {1, 0, 3, 3,
1334         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1335         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1336
1337         /* vertex shader and pixel shader */
1338         {1, 1, 0, 3,
1339         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1340         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1341         {1, 1, 1, 3,
1342         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1343         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1344         {1, 1, 2, 3,
1345         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1346         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1347
1348         {1, 1, 3, 3,
1349         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1350         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1351
1352
1353 #if 0  /* FIXME: these fail on GeForce 8500 */
1354         /* foggy vertex shader */
1355         {2, 0, 0, 0,
1356         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1357          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1358         {2, 0, 1, 0,
1359         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1360          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1361         {2, 0, 2, 0,
1362         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1363          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1364         {2, 0, 3, 0,
1365         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1366          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1367 #endif
1368
1369         /* foggy vertex shader and pixel shader */
1370         {2, 1, 0, 0,
1371         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1372          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1373         {2, 1, 1, 0,
1374         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1375          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1376         {2, 1, 2, 0,
1377         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1378          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1379         {2, 1, 3, 0,
1380         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1381          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1382
1383     };
1384
1385     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1386     start.f=0.1f;
1387     end.f=0.9f;
1388
1389     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1390     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1391     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1392     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1393     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1394     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1395     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1396     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1397
1398     /* Setup initial states: No lighting, fog on, fog color */
1399     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1400     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1401     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1402     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1403     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1404     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1405     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1406     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1407
1408     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1409     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1410     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1411     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1412
1413     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1415     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1417     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1418
1419     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1420     {
1421         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1422         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1423         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1424         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1425         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1426         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1427         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1428         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1429
1430         for(j=0; j < 11; j++)
1431         {
1432             /* Don't use the whole zrange to prevent rounding errors */
1433             quad[0].z = 0.001f + (float)j / 10.02f;
1434             quad[1].z = 0.001f + (float)j / 10.02f;
1435             quad[2].z = 0.001f + (float)j / 10.02f;
1436             quad[3].z = 0.001f + (float)j / 10.02f;
1437
1438             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1439             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1440
1441             hr = IDirect3DDevice9_BeginScene(device);
1442             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1443
1444             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1445             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1446
1447             hr = IDirect3DDevice9_EndScene(device);
1448             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1449
1450             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1451
1452             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1453             color = getPixelColor(device, 128, 240);
1454             ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1455                     && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1456                     && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1457                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1458                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1459         }
1460     }
1461
1462     /* reset states */
1463     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1464     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1465     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1466     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1467     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1468     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1469     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1470     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1471
1472     IDirect3DVertexShader9_Release(vertex_shader[1]);
1473     IDirect3DVertexShader9_Release(vertex_shader[2]);
1474     IDirect3DPixelShader9_Release(pixel_shader[1]);
1475     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1476 }
1477
1478 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1479     unsigned int i, x, y;
1480     HRESULT hr;
1481     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1482     D3DLOCKED_RECT locked_rect;
1483
1484     /* Generate the textures */
1485     for(i=0; i<2; i++)
1486     {
1487         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1488                                             D3DPOOL_MANAGED, &texture[i], NULL);
1489         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1490
1491         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1492         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1493         for (y = 0; y < 128; ++y)
1494         {
1495             if(i)
1496             { /* Set up black texture with 2x2 texel white spot in the middle */
1497                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1498                 for (x = 0; x < 128; ++x)
1499                 {
1500                     if(y>62 && y<66 && x>62 && x<66)
1501                         *ptr++ = 0xffffffff;
1502                     else
1503                         *ptr++ = 0xff000000;
1504                 }
1505             }
1506             else
1507             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1508                * (if multiplied with bumpenvmat)
1509               */
1510                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1511                 for (x = 0; x < 128; ++x)
1512                 {
1513                     if(abs(x-64)>abs(y-64))
1514                     {
1515                         if(x < 64)
1516                             *ptr++ = 0xc000;
1517                         else
1518                             *ptr++ = 0x4000;
1519                     }
1520                     else
1521                     {
1522                         if(y < 64)
1523                             *ptr++ = 0x0040;
1524                         else
1525                             *ptr++ = 0x00c0;
1526                     }
1527                 }
1528             }
1529         }
1530         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1531         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1532
1533         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1534         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1535
1536         /* Disable texture filtering */
1537         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1538         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1539         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1540         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1541
1542         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1543         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1544         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1545         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1546     }
1547 }
1548
1549 /* test the behavior of the texbem instruction
1550  * with normal 2D and projective 2D textures
1551  */
1552 static void texbem_test(IDirect3DDevice9 *device)
1553 {
1554     HRESULT hr;
1555     DWORD color;
1556     int i;
1557
1558     static const DWORD pixel_shader_code[] = {
1559         0xffff0101,                         /* ps_1_1*/
1560         0x00000042, 0xb00f0000,             /* tex t0*/
1561         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1562         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1563         0x0000ffff
1564     };
1565     static const DWORD double_texbem_code[] =  {
1566         0xffff0103,                                         /* ps_1_3           */
1567         0x00000042, 0xb00f0000,                             /* tex t0           */
1568         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1569         0x00000042, 0xb00f0002,                             /* tex t2           */
1570         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1571         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1572         0x0000ffff                                          /* end              */
1573     };
1574
1575
1576     static const float quad[][7] = {
1577         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1578         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1579         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1580         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1581     };
1582     static const float quad_proj[][9] = {
1583         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1584         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1585         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1586         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1587     };
1588
1589     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1590         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1591         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1592         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1593         D3DDECL_END()
1594     },{
1595         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1596         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1597         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1598         D3DDECL_END()
1599     } };
1600
1601     /* use asymmetric matrix to test loading */
1602     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1603
1604     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1605     IDirect3DPixelShader9       *pixel_shader       = NULL;
1606     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1607     D3DLOCKED_RECT locked_rect;
1608
1609     generate_bumpmap_textures(device);
1610
1611     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1612     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1613     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1614     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1615     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1616
1617     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1618     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1619
1620     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1621     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1622
1623     for(i=0; i<2; i++)
1624     {
1625         if(i)
1626         {
1627             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1628             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1629         }
1630
1631         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1632         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1633         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1634         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1635
1636         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1637         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1638         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1639         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1640
1641         hr = IDirect3DDevice9_BeginScene(device);
1642         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1643
1644         if(!i)
1645             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1646         else
1647             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1648         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1649
1650         hr = IDirect3DDevice9_EndScene(device);
1651         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1652
1653         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1654         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1655
1656         color = getPixelColor(device, 320-32, 240);
1657         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1658         color = getPixelColor(device, 320+32, 240);
1659         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1660         color = getPixelColor(device, 320, 240-32);
1661         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1662         color = getPixelColor(device, 320, 240+32);
1663         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1664
1665         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1666         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1667         IDirect3DPixelShader9_Release(pixel_shader);
1668
1669         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1670         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1671         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1672     }
1673
1674     /* clean up */
1675     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1676     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1677
1678     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1679     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1680
1681     for(i=0; i<2; i++)
1682     {
1683         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1684         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1685         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1686         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1687         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1688         IDirect3DTexture9_Release(texture);
1689     }
1690
1691     /* Test double texbem */
1692     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1693     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1694     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1695     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1696     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1697     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1698     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1699     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1700
1701     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1702     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1703     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1704     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1705
1706     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1707     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1708
1709     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1710     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1711     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1712     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1713     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1714     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1715
1716     {
1717         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1718 #define tex  0x00ff0000
1719 #define tex1 0x0000ff00
1720 #define origin 0x000000ff
1721         static const DWORD pixel_data[] = {
1722             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1723             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1724             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1725             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1726             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1727             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1728             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1729             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1730         };
1731 #undef tex1
1732 #undef tex2
1733 #undef origin
1734
1735         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1736         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1737         for(i = 0; i < 8; i++) {
1738             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1739         }
1740         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1741         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1742     }
1743
1744     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1745     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1746     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1747     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1748     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1749     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1750     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1751     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1752     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1753     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1754     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1755     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1756
1757     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1758     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1759     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1760     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1761     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1762     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1763
1764     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1765     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1766     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1767     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1768     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1769     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1770
1771     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1772     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1773     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1775     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1776     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1777     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1778     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1779
1780     hr = IDirect3DDevice9_BeginScene(device);
1781     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1782     if(SUCCEEDED(hr)) {
1783         static const float double_quad[] = {
1784             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1785              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1786             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1787              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1788         };
1789
1790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1791         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1792         hr = IDirect3DDevice9_EndScene(device);
1793         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1794     }
1795     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1796     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1797     color = getPixelColor(device, 320, 240);
1798     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1799
1800     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1801     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1802     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1803     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1804     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1805     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1806     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1807     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1808     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1809     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1810
1811     IDirect3DPixelShader9_Release(pixel_shader);
1812     IDirect3DTexture9_Release(texture);
1813     IDirect3DTexture9_Release(texture1);
1814     IDirect3DTexture9_Release(texture2);
1815 }
1816
1817 static void z_range_test(IDirect3DDevice9 *device)
1818 {
1819     const struct vertex quad[] =
1820     {
1821         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1822         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1823         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1824         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1825     };
1826     const struct vertex quad2[] =
1827     {
1828         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1829         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1830         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1831         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1832     };
1833
1834     const struct tvertex quad3[] =
1835     {
1836         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1837         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1838         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1839         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1840     };
1841     const struct tvertex quad4[] =
1842     {
1843         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1844         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1845         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1846         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1847     };
1848     HRESULT hr;
1849     DWORD color;
1850     IDirect3DVertexShader9 *shader;
1851     IDirect3DVertexDeclaration9 *decl;
1852     D3DCAPS9 caps;
1853     const DWORD shader_code[] = {
1854         0xfffe0101,                                     /* vs_1_1           */
1855         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1856         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1857         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1858         0x0000ffff                                      /* end              */
1859     };
1860     static const D3DVERTEXELEMENT9 decl_elements[] = {
1861         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1862         D3DDECL_END()
1863     };
1864     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1865      * then call Present. Then clear the color buffer to make sure it has some defined content
1866      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1867      * by the depth value.
1868      */
1869     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1870     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1871     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1872     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1873
1874     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1875     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1876     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1877     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1878     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1879     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1880     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1881     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1882     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1883     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1884
1885     hr = IDirect3DDevice9_BeginScene(device);
1886     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1887     if(hr == D3D_OK)
1888     {
1889         /* Test the untransformed vertex path */
1890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1891         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1892         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1893         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1895         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1896
1897         /* Test the transformed vertex path */
1898         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1899         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1900
1901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1902         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1903         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1904         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1905         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1906         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1907
1908         hr = IDirect3DDevice9_EndScene(device);
1909         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1910     }
1911
1912     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1913     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1914
1915     /* Do not test the exact corner pixels, but go pretty close to them */
1916
1917     /* Clipped because z > 1.0 */
1918     color = getPixelColor(device, 28, 238);
1919     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1920     color = getPixelColor(device, 28, 241);
1921     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1922
1923     /* Not clipped, > z buffer clear value(0.75) */
1924     color = getPixelColor(device, 31, 238);
1925     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1926     color = getPixelColor(device, 31, 241);
1927     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1928     color = getPixelColor(device, 100, 238);
1929     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1930     color = getPixelColor(device, 100, 241);
1931     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1932
1933     /* Not clipped, < z buffer clear value */
1934     color = getPixelColor(device, 104, 238);
1935     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1936     color = getPixelColor(device, 104, 241);
1937     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1938     color = getPixelColor(device, 318, 238);
1939     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1940     color = getPixelColor(device, 318, 241);
1941     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1942
1943     /* Clipped because z < 0.0 */
1944     color = getPixelColor(device, 321, 238);
1945     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1946     color = getPixelColor(device, 321, 241);
1947     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1948
1949     /* Test the shader path */
1950     IDirect3DDevice9_GetDeviceCaps(device, &caps);
1951     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1952         skip("Vertex shaders not supported\n");
1953         goto out;
1954     }
1955     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1956     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1957     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1958     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1959
1960     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1961
1962     IDirect3DDevice9_SetVertexDeclaration(device, decl);
1963     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1964     IDirect3DDevice9_SetVertexShader(device, shader);
1965     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1966
1967     hr = IDirect3DDevice9_BeginScene(device);
1968     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1969     if(hr == D3D_OK)
1970     {
1971         float colorf[] = {1.0, 0.0, 0.0, 1.0};
1972         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1973         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1974         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1975         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1976         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1977         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1978         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1980         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1981
1982         hr = IDirect3DDevice9_EndScene(device);
1983         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1984     }
1985
1986     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1987     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1988     IDirect3DDevice9_SetVertexShader(device, NULL);
1989     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1990
1991     IDirect3DVertexDeclaration9_Release(decl);
1992     IDirect3DVertexShader9_Release(shader);
1993
1994     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1995     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1996     /* Z < 1.0 */
1997     color = getPixelColor(device, 28, 238);
1998     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1999
2000     /* 1.0 < z < 0.75 */
2001     color = getPixelColor(device, 31, 238);
2002     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2003     color = getPixelColor(device, 100, 238);
2004     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2005
2006     /* 0.75 < z < 0.0 */
2007     color = getPixelColor(device, 104, 238);
2008     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2009     color = getPixelColor(device, 318, 238);
2010     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2011
2012     /* 0.0 < z */
2013     color = getPixelColor(device, 321, 238);
2014     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2015
2016     out:
2017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2018     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2020     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2021     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2022     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2023 }
2024
2025 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2026 {
2027     D3DSURFACE_DESC desc;
2028     D3DLOCKED_RECT l;
2029     HRESULT hr;
2030     unsigned int x, y;
2031     DWORD *mem;
2032
2033     memset(&desc, 0, sizeof(desc));
2034     memset(&l, 0, sizeof(l));
2035     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2036     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2037     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2038     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2039     if(FAILED(hr)) return;
2040
2041     for(y = 0; y < desc.Height; y++)
2042     {
2043         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2044         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2045         {
2046             mem[x] = color;
2047         }
2048     }
2049     hr = IDirect3DSurface9_UnlockRect(surface);
2050     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2051 }
2052
2053 /* This tests a variety of possible StretchRect() situations */
2054 static void stretchrect_test(IDirect3DDevice9 *device)
2055 {
2056     HRESULT hr;
2057     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2058     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2059     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2060     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2061     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2062     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2063     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2064     IDirect3DSurface9 *orig_rt = NULL;
2065     DWORD color;
2066
2067     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2068     ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2069     if(!orig_rt) {
2070         goto out;
2071     }
2072
2073     /* Create our temporary surfaces in system memory */
2074     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2075     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2076     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2077     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2078
2079     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2080     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2081     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2082     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2083     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2084     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2085     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2086
2087     /* Create render target surfaces */
2088     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2089     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2090     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2091     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2092     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2093     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2094
2095     /* Create render target textures */
2096     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2097     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2098     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2099     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2100     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2101     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2102     if (tex_rt32) {
2103         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2104         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2105     }
2106     if (tex_rt64) {
2107         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2108         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2109     }
2110     if (tex_rt_dest64) {
2111         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2112         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2113     }
2114
2115     /* Create regular textures in D3DPOOL_DEFAULT */
2116     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2117     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2118     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2119     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2120     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2121     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2122     if (tex32) {
2123         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2124         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2125     }
2126     if (tex64) {
2127         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2128         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2129     }
2130     if (tex_dest64) {
2131         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2132         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2133     }
2134
2135     /*********************************************************************
2136      * Tests for when the source parameter is an offscreen plain surface *
2137      *********************************************************************/
2138
2139     /* Fill the offscreen 64x64 surface with green */
2140     if (surf_offscreen64)
2141         fill_surface(surf_offscreen64, 0xff00ff00);
2142
2143     /* offscreenplain ==> offscreenplain, same size */
2144     if(surf_offscreen64 && surf_offscreen_dest64) {
2145         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2146         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2147
2148         if (hr == D3D_OK) {
2149             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2150             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2151         }
2152     }
2153
2154     /* offscreenplain ==> rendertarget texture, same size */
2155     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2156         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2157         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2158
2159         /* We can't lock rendertarget textures, so copy to our temp surface first */
2160         if (hr == D3D_OK) {
2161             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2162             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2163         }
2164
2165         if (hr == D3D_OK) {
2166             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2167             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2168         }
2169     }
2170
2171     /* offscreenplain ==> rendertarget surface, same size */
2172     if(surf_offscreen64 && surf_rt_dest64) {
2173         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2174         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2175
2176         if (hr == D3D_OK) {
2177             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2178             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2179         }
2180     }
2181
2182     /* offscreenplain ==> texture, same size (should fail) */
2183     if(surf_offscreen64 && surf_tex_dest64) {
2184         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2185         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2186     }
2187
2188     /* Fill the smaller offscreen surface with red */
2189     fill_surface(surf_offscreen32, 0xffff0000);
2190
2191     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2192     if(surf_offscreen32 && surf_offscreen64) {
2193         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2194         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2195     }
2196
2197     /* offscreenplain ==> rendertarget texture, scaling */
2198     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2199         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2200         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2201
2202         /* We can't lock rendertarget textures, so copy to our temp surface first */
2203         if (hr == D3D_OK) {
2204             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2205             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2206         }
2207
2208         if (hr == D3D_OK) {
2209             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2210             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2211         }
2212     }
2213
2214     /* offscreenplain ==> rendertarget surface, scaling */
2215     if(surf_offscreen32 && surf_rt_dest64) {
2216         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2217         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2218
2219         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2220         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2221     }
2222
2223     /* offscreenplain ==> texture, scaling (should fail) */
2224     if(surf_offscreen32 && surf_tex_dest64) {
2225         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2226         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2227     }
2228
2229     /************************************************************
2230      * Tests for when the source parameter is a regular texture *
2231      ************************************************************/
2232
2233     /* Fill the surface of the regular texture with blue */
2234     if (surf_tex64 && surf_temp64) {
2235         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2236         fill_surface(surf_temp64, 0xff0000ff);
2237         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2238         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2239     }
2240
2241     /* texture ==> offscreenplain, same size */
2242     if(surf_tex64 && surf_offscreen64) {
2243         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2244         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2245     }
2246
2247     /* texture ==> rendertarget texture, same size */
2248     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2249         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2250         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2251
2252         /* We can't lock rendertarget textures, so copy to our temp surface first */
2253         if (hr == D3D_OK) {
2254             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2255             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2256         }
2257
2258         if (hr == D3D_OK) {
2259             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2260             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2261         }
2262     }
2263
2264     /* texture ==> rendertarget surface, same size */
2265     if(surf_tex64 && surf_rt_dest64) {
2266         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2267         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2268
2269         if (hr == D3D_OK) {
2270             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2271             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2272         }
2273     }
2274
2275     /* texture ==> texture, same size (should fail) */
2276     if(surf_tex64 && surf_tex_dest64) {
2277         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2278         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2279     }
2280
2281     /* Fill the surface of the smaller regular texture with red */
2282     if (surf_tex32 && surf_temp32) {
2283         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2284         fill_surface(surf_temp32, 0xffff0000);
2285         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2286         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2287     }
2288
2289     /* texture ==> offscreenplain, scaling (should fail) */
2290     if(surf_tex32 && surf_offscreen64) {
2291         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2292         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2293     }
2294
2295     /* texture ==> rendertarget texture, scaling */
2296     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2297         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2298         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2299
2300         /* We can't lock rendertarget textures, so copy to our temp surface first */
2301         if (hr == D3D_OK) {
2302             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2303             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2304         }
2305
2306         if (hr == D3D_OK) {
2307             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2308             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2309         }
2310     }
2311
2312     /* texture ==> rendertarget surface, scaling */
2313     if(surf_tex32 && surf_rt_dest64) {
2314         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2315         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2316
2317         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2318         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2319     }
2320
2321     /* texture ==> texture, scaling (should fail) */
2322     if(surf_tex32 && surf_tex_dest64) {
2323         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2324         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2325     }
2326
2327     /*****************************************************************
2328      * Tests for when the source parameter is a rendertarget texture *
2329      *****************************************************************/
2330
2331     /* Fill the surface of the rendertarget texture with white */
2332     if (surf_tex_rt64 && surf_temp64) {
2333         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2334         fill_surface(surf_temp64, 0xffffffff);
2335         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2336         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2337     }
2338
2339     /* rendertarget texture ==> offscreenplain, same size */
2340     if(surf_tex_rt64 && surf_offscreen64) {
2341         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2342         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2343     }
2344
2345     /* rendertarget texture ==> rendertarget texture, same size */
2346     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2347         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2348         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2349
2350         /* We can't lock rendertarget textures, so copy to our temp surface first */
2351         if (hr == D3D_OK) {
2352             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2353             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2354         }
2355
2356         if (hr == D3D_OK) {
2357             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2358             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2359         }
2360     }
2361
2362     /* rendertarget texture ==> rendertarget surface, same size */
2363     if(surf_tex_rt64 && surf_rt_dest64) {
2364         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2365         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2366
2367         if (hr == D3D_OK) {
2368             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2369             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2370         }
2371     }
2372
2373     /* rendertarget texture ==> texture, same size (should fail) */
2374     if(surf_tex_rt64 && surf_tex_dest64) {
2375         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2376         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2377     }
2378
2379     /* Fill the surface of the smaller rendertarget texture with red */
2380     if (surf_tex_rt32 && surf_temp32) {
2381         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2382         fill_surface(surf_temp32, 0xffff0000);
2383         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2384         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2385     }
2386
2387     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2388     if(surf_tex_rt32 && surf_offscreen64) {
2389         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2390         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2391     }
2392
2393     /* rendertarget texture ==> rendertarget texture, scaling */
2394     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2395         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2396         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2397
2398         /* We can't lock rendertarget textures, so copy to our temp surface first */
2399         if (hr == D3D_OK) {
2400             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2401             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2402         }
2403
2404         if (hr == D3D_OK) {
2405             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2406             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2407         }
2408     }
2409
2410     /* rendertarget texture ==> rendertarget surface, scaling */
2411     if(surf_tex_rt32 && surf_rt_dest64) {
2412         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2413         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2414
2415         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2416         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2417     }
2418
2419     /* rendertarget texture ==> texture, scaling (should fail) */
2420     if(surf_tex_rt32 && surf_tex_dest64) {
2421         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2422         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2423     }
2424
2425     /*****************************************************************
2426      * Tests for when the source parameter is a rendertarget surface *
2427      *****************************************************************/
2428
2429     /* Fill the surface of the rendertarget surface with black */
2430     if (surf_rt64)
2431         fill_surface(surf_rt64, 0xff000000);
2432
2433     /* rendertarget texture ==> offscreenplain, same size */
2434     if(surf_rt64 && surf_offscreen64) {
2435         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2436         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2437     }
2438
2439     /* rendertarget surface ==> rendertarget texture, same size */
2440     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2441         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2442         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2443
2444         /* We can't lock rendertarget textures, so copy to our temp surface first */
2445         if (hr == D3D_OK) {
2446             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2447             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2448         }
2449
2450         if (hr == D3D_OK) {
2451             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2452             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2453         }
2454     }
2455
2456     /* rendertarget surface ==> rendertarget surface, same size */
2457     if(surf_rt64 && surf_rt_dest64) {
2458         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2459         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2460
2461         if (hr == D3D_OK) {
2462             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2463             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2464         }
2465     }
2466
2467     /* rendertarget surface ==> texture, same size (should fail) */
2468     if(surf_rt64 && surf_tex_dest64) {
2469         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2470         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2471     }
2472
2473     /* Fill the surface of the smaller rendertarget texture with red */
2474     if (surf_rt32)
2475         fill_surface(surf_rt32, 0xffff0000);
2476
2477     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2478     if(surf_rt32 && surf_offscreen64) {
2479         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2481     }
2482
2483     /* rendertarget surface ==> rendertarget texture, scaling */
2484     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2486         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2487
2488         /* We can't lock rendertarget textures, so copy to our temp surface first */
2489         if (hr == D3D_OK) {
2490             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2491             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2492         }
2493
2494         if (hr == D3D_OK) {
2495             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2496             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2497         }
2498     }
2499
2500     /* rendertarget surface ==> rendertarget surface, scaling */
2501     if(surf_rt32 && surf_rt_dest64) {
2502         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2503         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2504
2505         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2506         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2507     }
2508
2509     /* rendertarget surface ==> texture, scaling (should fail) */
2510     if(surf_rt32 && surf_tex_dest64) {
2511         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2512         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2513     }
2514
2515     /* TODO: Test when source and destination RECT parameters are given... */
2516     /* TODO: Test format conversions */
2517
2518
2519 out:
2520     /* Clean up */
2521     if (surf_rt32)
2522         IDirect3DSurface9_Release(surf_rt32);
2523     if (surf_rt64)
2524         IDirect3DSurface9_Release(surf_rt64);
2525     if (surf_rt_dest64)
2526         IDirect3DSurface9_Release(surf_rt_dest64);
2527     if (surf_temp32)
2528         IDirect3DSurface9_Release(surf_temp32);
2529     if (surf_temp64)
2530         IDirect3DSurface9_Release(surf_temp64);
2531     if (surf_offscreen32)
2532         IDirect3DSurface9_Release(surf_offscreen32);
2533     if (surf_offscreen64)
2534         IDirect3DSurface9_Release(surf_offscreen64);
2535     if (surf_offscreen_dest64)
2536         IDirect3DSurface9_Release(surf_offscreen_dest64);
2537
2538     if (tex_rt32) {
2539         if (surf_tex_rt32)
2540             IDirect3DSurface9_Release(surf_tex_rt32);
2541         IDirect3DTexture9_Release(tex_rt32);
2542     }
2543     if (tex_rt64) {
2544         if (surf_tex_rt64)
2545             IDirect3DSurface9_Release(surf_tex_rt64);
2546         IDirect3DTexture9_Release(tex_rt64);
2547     }
2548     if (tex_rt_dest64) {
2549         if (surf_tex_rt_dest64)
2550             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2551         IDirect3DTexture9_Release(tex_rt_dest64);
2552     }
2553     if (tex32) {
2554         if (surf_tex32)
2555             IDirect3DSurface9_Release(surf_tex32);
2556         IDirect3DTexture9_Release(tex32);
2557     }
2558     if (tex64) {
2559         if (surf_tex64)
2560             IDirect3DSurface9_Release(surf_tex64);
2561         IDirect3DTexture9_Release(tex64);
2562     }
2563     if (tex_dest64) {
2564         if (surf_tex_dest64)
2565             IDirect3DSurface9_Release(surf_tex_dest64);
2566         IDirect3DTexture9_Release(tex_dest64);
2567     }
2568
2569     if (orig_rt) {
2570         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2571         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2572         IDirect3DSurface9_Release(orig_rt);
2573     }
2574 }
2575
2576 static void maxmip_test(IDirect3DDevice9 *device)
2577 {
2578     IDirect3DTexture9 *texture = NULL;
2579     IDirect3DSurface9 *surface = NULL;
2580     HRESULT hr;
2581     DWORD color;
2582     const float quads[] = {
2583         -1.0,   -1.0,   0.0,    0.0,    0.0,
2584         -1.0,    0.0,   0.0,    0.0,    1.0,
2585          0.0,   -1.0,   0.0,    1.0,    0.0,
2586          0.0,    0.0,   0.0,    1.0,    1.0,
2587
2588          0.0,   -1.0,   0.0,    0.0,    0.0,
2589          0.0,    0.0,   0.0,    0.0,    1.0,
2590          1.0,   -1.0,   0.0,    1.0,    0.0,
2591          1.0,    0.0,   0.0,    1.0,    1.0,
2592
2593          0.0,    0.0,   0.0,    0.0,    0.0,
2594          0.0,    1.0,   0.0,    0.0,    1.0,
2595          1.0,    0.0,   0.0,    1.0,    0.0,
2596          1.0,    1.0,   0.0,    1.0,    1.0,
2597
2598         -1.0,    0.0,   0.0,    0.0,    0.0,
2599         -1.0,    1.0,   0.0,    0.0,    1.0,
2600          0.0,    0.0,   0.0,    1.0,    0.0,
2601          0.0,    1.0,   0.0,    1.0,    1.0,
2602     };
2603
2604     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2605     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2606
2607     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2608                                         &texture, NULL);
2609     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2610     if(!texture)
2611     {
2612         skip("Failed to create test texture\n");
2613         return;
2614     }
2615
2616     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2617     fill_surface(surface, 0xffff0000);
2618     IDirect3DSurface9_Release(surface);
2619     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2620     fill_surface(surface, 0xff00ff00);
2621     IDirect3DSurface9_Release(surface);
2622     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2623     fill_surface(surface, 0xff0000ff);
2624     IDirect3DSurface9_Release(surface);
2625
2626     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2627     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2628     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2629     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2630
2631     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2632     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2633
2634     hr = IDirect3DDevice9_BeginScene(device);
2635     if(SUCCEEDED(hr))
2636     {
2637         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2638         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2639         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2640         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2641
2642         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2643         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2644         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2645         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2646
2647         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2648         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2649         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2650         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2651
2652         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2653         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2654         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2655         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2656         hr = IDirect3DDevice9_EndScene(device);
2657     }
2658
2659     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2660     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2661     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2662     color = getPixelColor(device, 160, 360);
2663     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2664     color = getPixelColor(device, 160, 120);
2665     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2666     color = getPixelColor(device, 480, 120);
2667     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2668     color = getPixelColor(device, 480, 360);
2669     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2670
2671     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2672     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2673
2674     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2675     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2676
2677     hr = IDirect3DDevice9_BeginScene(device);
2678     if(SUCCEEDED(hr))
2679     {
2680         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2681         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2682         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2683         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2684
2685         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2686         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2687         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2688         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2689
2690         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2691         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2693         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2694
2695         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2696         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2697         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2698         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2699         hr = IDirect3DDevice9_EndScene(device);
2700     }
2701
2702     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2703     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2704     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2705     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2706
2707     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2708     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2709     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2710      * samples from the highest level in the texture(level 2)
2711      */
2712     color = getPixelColor(device, 160, 360);
2713     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2714     color = getPixelColor(device, 160, 120);
2715     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2716     color = getPixelColor(device, 480, 120);
2717     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2718     color = getPixelColor(device, 480, 360);
2719     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2720
2721     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2722     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2723     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2724     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2725     IDirect3DTexture9_Release(texture);
2726 }
2727
2728 static void release_buffer_test(IDirect3DDevice9 *device)
2729 {
2730     IDirect3DVertexBuffer9 *vb = NULL;
2731     IDirect3DIndexBuffer9 *ib = NULL;
2732     HRESULT hr;
2733     BYTE *data;
2734     long ref;
2735
2736     static const struct vertex quad[] = {
2737         {-1.0,      -1.0,       0.1,        0xffff0000},
2738         {-1.0,       1.0,       0.1,        0xffff0000},
2739         { 1.0,       1.0,       0.1,        0xffff0000},
2740
2741         {-1.0,      -1.0,       0.1,        0xff00ff00},
2742         {-1.0,       1.0,       0.1,        0xff00ff00},
2743         { 1.0,       1.0,       0.1,        0xff00ff00}
2744     };
2745     short indices[] = {3, 4, 5};
2746
2747     /* Index and vertex buffers should always be creatable */
2748     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2749                                               D3DPOOL_MANAGED, &vb, NULL);
2750     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2751     if(!vb) {
2752         skip("Failed to create a vertex buffer\n");
2753         return;
2754     }
2755     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2756     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2757     if(!ib) {
2758         skip("Failed to create an index buffer\n");
2759         return;
2760     }
2761
2762     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2763     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2764     memcpy(data, quad, sizeof(quad));
2765     hr = IDirect3DVertexBuffer9_Unlock(vb);
2766     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2767
2768     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2769     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2770     memcpy(data, indices, sizeof(indices));
2771     hr = IDirect3DIndexBuffer9_Unlock(ib);
2772     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2773
2774     hr = IDirect3DDevice9_SetIndices(device, ib);
2775     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %s\n", DXGetErrorString9(hr));
2776     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2777     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
2778     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2779     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2780
2781     /* Now destroy the bound index buffer and draw again */
2782     ref = IDirect3DIndexBuffer9_Release(ib);
2783     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2784
2785     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2786     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2787
2788     hr = IDirect3DDevice9_BeginScene(device);
2789     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2790     if(SUCCEEDED(hr))
2791     {
2792         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2793          * making assumptions about the indices or vertices
2794          */
2795         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2796         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2797         hr = IDirect3DDevice9_EndScene(device);
2798         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2799     }
2800
2801     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2802     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2803
2804     hr = IDirect3DDevice9_SetIndices(device, NULL);
2805     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2806     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2807     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2808
2809     /* Index buffer was already destroyed as part of the test */
2810     IDirect3DVertexBuffer9_Release(vb);
2811 }
2812
2813 static void float_texture_test(IDirect3DDevice9 *device)
2814 {
2815     IDirect3D9 *d3d = NULL;
2816     HRESULT hr;
2817     IDirect3DTexture9 *texture = NULL;
2818     D3DLOCKED_RECT lr;
2819     float *data;
2820     DWORD color;
2821     float quad[] = {
2822         -1.0,      -1.0,       0.1,     0.0,    0.0,
2823         -1.0,       1.0,       0.1,     0.0,    1.0,
2824          1.0,      -1.0,       0.1,     1.0,    0.0,
2825          1.0,       1.0,       0.1,     1.0,    1.0,
2826     };
2827
2828     memset(&lr, 0, sizeof(lr));
2829     IDirect3DDevice9_GetDirect3D(device, &d3d);
2830     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2831                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2832         skip("D3DFMT_R32F textures not supported\n");
2833         goto out;
2834     }
2835
2836     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2837                                         D3DPOOL_MANAGED, &texture, NULL);
2838     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2839     if(!texture) {
2840         skip("Failed to create R32F texture\n");
2841         goto out;
2842     }
2843
2844     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2845     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2846     data = lr.pBits;
2847     *data = 0.0;
2848     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2849     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2850
2851     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2852     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2853
2854     hr = IDirect3DDevice9_BeginScene(device);
2855     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2856     if(SUCCEEDED(hr))
2857     {
2858         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2859         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2860
2861         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2862         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2863
2864         hr = IDirect3DDevice9_EndScene(device);
2865         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2866     }
2867     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2868     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2869
2870     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2871     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2872
2873     color = getPixelColor(device, 240, 320);
2874     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2875
2876 out:
2877     if(texture) IDirect3DTexture9_Release(texture);
2878     IDirect3D9_Release(d3d);
2879 }
2880
2881 static void g16r16_texture_test(IDirect3DDevice9 *device)
2882 {
2883     IDirect3D9 *d3d = NULL;
2884     HRESULT hr;
2885     IDirect3DTexture9 *texture = NULL;
2886     D3DLOCKED_RECT lr;
2887     DWORD *data;
2888     DWORD color, red, green, blue;
2889     float quad[] = {
2890        -1.0,      -1.0,       0.1,     0.0,    0.0,
2891        -1.0,       1.0,       0.1,     0.0,    1.0,
2892         1.0,      -1.0,       0.1,     1.0,    0.0,
2893         1.0,       1.0,       0.1,     1.0,    1.0,
2894     };
2895
2896     memset(&lr, 0, sizeof(lr));
2897     IDirect3DDevice9_GetDirect3D(device, &d3d);
2898     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2899        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2900            skip("D3DFMT_G16R16 textures not supported\n");
2901            goto out;
2902     }
2903
2904     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2905                                         D3DPOOL_MANAGED, &texture, NULL);
2906     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2907     if(!texture) {
2908         skip("Failed to create D3DFMT_G16R16 texture\n");
2909         goto out;
2910     }
2911
2912     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2913     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2914     data = lr.pBits;
2915     *data = 0x0f00f000;
2916     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2917     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2918
2919     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2920     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2921
2922     hr = IDirect3DDevice9_BeginScene(device);
2923     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2924     if(SUCCEEDED(hr))
2925     {
2926         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2927         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2928
2929         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2930         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2931
2932         hr = IDirect3DDevice9_EndScene(device);
2933         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2934     }
2935     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2936     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2937
2938     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2939     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2940
2941     color = getPixelColor(device, 240, 320);
2942     red   = (color & 0x00ff0000) >> 16;
2943     green = (color & 0x0000ff00) >>  8;
2944     blue  = (color & 0x000000ff) >>  0;
2945     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2946        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2947
2948 out:
2949     if(texture) IDirect3DTexture9_Release(texture);
2950     IDirect3D9_Release(d3d);
2951 }
2952
2953 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2954 {
2955     HRESULT hr;
2956     IDirect3D9 *d3d;
2957     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2958     D3DCAPS9 caps;
2959     IDirect3DTexture9 *texture = NULL;
2960     IDirect3DVolumeTexture9 *volume = NULL;
2961     unsigned int x, y, z;
2962     D3DLOCKED_RECT lr;
2963     D3DLOCKED_BOX lb;
2964     DWORD color;
2965     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2966     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2967                            0.0, 1.0, 0.0, 0.0,
2968                            0.0, 0.0, 1.0, 0.0,
2969                            0.0, 0.0, 0.0, 1.0};
2970     static const D3DVERTEXELEMENT9 decl_elements[] = {
2971         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2972         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2973         D3DDECL_END()
2974     };
2975     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2976         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2977         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2978         D3DDECL_END()
2979     };
2980     static const D3DVERTEXELEMENT9 decl_elements3[] = {
2981         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2982         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2983         D3DDECL_END()
2984     };
2985     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2986                                                  0x00, 0xff, 0x00, 0x00,
2987                                                  0x00, 0x00, 0x00, 0x00,
2988                                                  0x00, 0x00, 0x00, 0x00};
2989
2990     memset(&lr, 0, sizeof(lr));
2991     memset(&lb, 0, sizeof(lb));
2992     IDirect3DDevice9_GetDirect3D(device, &d3d);
2993     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2994                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2995         fmt = D3DFMT_A16B16G16R16;
2996     }
2997     IDirect3D9_Release(d3d);
2998
2999     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3000     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3001     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3002     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3003     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3004     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3005     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3006     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
3007     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3008     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
3009     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3010     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
3011     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3012     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
3013     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3014     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3015     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3016     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3017     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3018     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3020     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3021     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3022     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3023
3024     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3025     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3026     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3027                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3028     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3029     if(!texture) {
3030         skip("Failed to create the test texture\n");
3031         return;
3032     }
3033
3034     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3035      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3036      * 1.0 in red and green for the x and y coords
3037      */
3038     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3039     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3040     for(y = 0; y < caps.MaxTextureHeight; y++) {
3041         for(x = 0; x < caps.MaxTextureWidth; x++) {
3042             double r_f = (double) y / (double) caps.MaxTextureHeight;
3043             double g_f = (double) x / (double) caps.MaxTextureWidth;
3044             if(fmt == D3DFMT_A16B16G16R16) {
3045                 unsigned short r, g;
3046                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3047                 r = (unsigned short) (r_f * 65536.0);
3048                 g = (unsigned short) (g_f * 65536.0);
3049                 dst[0] = r;
3050                 dst[1] = g;
3051                 dst[2] = 0;
3052                 dst[3] = 65535;
3053             } else {
3054                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3055                 unsigned char r = (unsigned char) (r_f * 255.0);
3056                 unsigned char g = (unsigned char) (g_f * 255.0);
3057                 dst[0] = 0;
3058                 dst[1] = g;
3059                 dst[2] = r;
3060                 dst[3] = 255;
3061             }
3062         }
3063     }
3064     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3065     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3066     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3067     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3068
3069     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3070     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3071     hr = IDirect3DDevice9_BeginScene(device);
3072     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3073     if(SUCCEEDED(hr))
3074     {
3075         float quad1[] = {
3076             -1.0,      -1.0,       0.1,     1.0,    1.0,
3077             -1.0,       0.0,       0.1,     1.0,    1.0,
3078              0.0,      -1.0,       0.1,     1.0,    1.0,
3079              0.0,       0.0,       0.1,     1.0,    1.0,
3080         };
3081         float quad2[] = {
3082             -1.0,       0.0,       0.1,     1.0,    1.0,
3083             -1.0,       1.0,       0.1,     1.0,    1.0,
3084              0.0,       0.0,       0.1,     1.0,    1.0,
3085              0.0,       1.0,       0.1,     1.0,    1.0,
3086         };
3087         float quad3[] = {
3088              0.0,       0.0,       0.1,     0.5,    0.5,
3089              0.0,       1.0,       0.1,     0.5,    0.5,
3090              1.0,       0.0,       0.1,     0.5,    0.5,
3091              1.0,       1.0,       0.1,     0.5,    0.5,
3092         };
3093         float quad4[] = {
3094              320,       480,       0.1,     1.0,    0.0,    1.0,
3095              320,       240,       0.1,     1.0,    0.0,    1.0,
3096              640,       480,       0.1,     1.0,    0.0,    1.0,
3097              640,       240,       0.1,     1.0,    0.0,    1.0,
3098         };
3099         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3100                           0.0, 0.0, 0.0, 0.0,
3101                           0.0, 0.0, 0.0, 0.0,
3102                           0.0, 0.0, 0.0, 0.0};
3103
3104         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3105         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3106         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3107         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3108         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3109
3110         /* What happens with transforms enabled? */
3111         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3112         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3113         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3114         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3115
3116         /* What happens if 4 coords are used, but only 2 given ?*/
3117         mat[8] = 1.0;
3118         mat[13] = 1.0;
3119         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3120         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3121         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3122         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3124         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3125
3126         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3127          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3128          * due to the coords in the vertices. (turns out red, indeed)
3129          */
3130         memset(mat, 0, sizeof(mat));
3131         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3133         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3134         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3135         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3136         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139
3140         hr = IDirect3DDevice9_EndScene(device);
3141         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3142     }
3143     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3144     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3145     color = getPixelColor(device, 160, 360);
3146     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3147     color = getPixelColor(device, 160, 120);
3148     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3149     color = getPixelColor(device, 480, 120);
3150     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3151     color = getPixelColor(device, 480, 360);
3152     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3153
3154     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3155     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3156
3157     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3158     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3159     hr = IDirect3DDevice9_BeginScene(device);
3160     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3161     if(SUCCEEDED(hr))
3162     {
3163         float quad1[] = {
3164             -1.0,      -1.0,       0.1,     0.8,    0.2,
3165             -1.0,       0.0,       0.1,     0.8,    0.2,
3166              0.0,      -1.0,       0.1,     0.8,    0.2,
3167              0.0,       0.0,       0.1,     0.8,    0.2,
3168         };
3169         float quad2[] = {
3170             -1.0,       0.0,       0.1,     0.5,    1.0,
3171             -1.0,       1.0,       0.1,     0.5,    1.0,
3172              0.0,       0.0,       0.1,     0.5,    1.0,
3173              0.0,       1.0,       0.1,     0.5,    1.0,
3174         };
3175         float quad3[] = {
3176              0.0,       0.0,       0.1,     0.5,    1.0,
3177              0.0,       1.0,       0.1,     0.5,    1.0,
3178              1.0,       0.0,       0.1,     0.5,    1.0,
3179              1.0,       1.0,       0.1,     0.5,    1.0,
3180         };
3181         float quad4[] = {
3182              0.0,      -1.0,       0.1,     0.8,    0.2,
3183              0.0,       0.0,       0.1,     0.8,    0.2,
3184              1.0,      -1.0,       0.1,     0.8,    0.2,
3185              1.0,       0.0,       0.1,     0.8,    0.2,
3186         };
3187         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3188                           0.0, 0.0, 0.0, 0.0,
3189                           0.0, 1.0, 0.0, 0.0,
3190                           0.0, 0.0, 0.0, 0.0};
3191
3192         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3193          */
3194         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3195         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3196         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3197         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3198
3199         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3200         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3201
3202         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3203          * it behaves like COUNT2 because normal textures require 2 coords
3204          */
3205         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3206         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3207         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3208         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3209
3210         /* Just to be sure, the same as quad2 above */
3211         memset(mat, 0, sizeof(mat));
3212         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3213         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3214         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3215         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3216         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3217         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3218
3219         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3220          * used? And what happens to the first?
3221          */
3222         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3223         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3225         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3226
3227         hr = IDirect3DDevice9_EndScene(device);
3228         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3229     }
3230     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3231     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3232     color = getPixelColor(device, 160, 360);
3233     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3234     color = getPixelColor(device, 160, 120);
3235     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3236     color = getPixelColor(device, 480, 120);
3237     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3238        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3239     color = getPixelColor(device, 480, 360);
3240     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3241        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3242
3243     IDirect3DTexture9_Release(texture);
3244
3245     /* Test projected textures, without any fancy matrices */
3246     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3247     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3248     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3249     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3250     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3251     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3252     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3253     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3254
3255     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3256     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3257     for(x = 0; x < 4; x++) {
3258         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3259     }
3260     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3261     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3262     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3263     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3264
3265     hr = IDirect3DDevice9_BeginScene(device);
3266     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3267     if(SUCCEEDED(hr))
3268     {
3269         const float proj_quads[] = {
3270            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3271             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3272            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3273             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3274            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3275             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3276            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3277             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3278         };
3279
3280         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3281         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3283         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3284
3285         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3286         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3287         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3288         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3289
3290         hr = IDirect3DDevice9_EndScene(device);
3291         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3292     }
3293
3294     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3295     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3296     IDirect3DTexture9_Release(texture);
3297
3298     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3299     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3300     color = getPixelColor(device, 158, 118);
3301     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3302     color = getPixelColor(device, 162, 118);
3303     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3304     color = getPixelColor(device, 158, 122);
3305     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3306     color = getPixelColor(device, 162, 122);
3307     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3308
3309     color = getPixelColor(device, 158, 178);
3310     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3311     color = getPixelColor(device, 162, 178);
3312     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3313     color = getPixelColor(device, 158, 182);
3314     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3315     color = getPixelColor(device, 162, 182);
3316     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3317
3318     color = getPixelColor(device, 318, 118);
3319     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3320     color = getPixelColor(device, 322, 118);
3321     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3322     color = getPixelColor(device, 318, 122);
3323     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3324     color = getPixelColor(device, 322, 122);
3325     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3326
3327     color = getPixelColor(device, 318, 178);
3328     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3329     color = getPixelColor(device, 322, 178);
3330     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3331     color = getPixelColor(device, 318, 182);
3332     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3333     color = getPixelColor(device, 322, 182);
3334     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3335
3336     color = getPixelColor(device, 238, 298);
3337     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3338     color = getPixelColor(device, 242, 298);
3339     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3340     color = getPixelColor(device, 238, 302);
3341     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3342     color = getPixelColor(device, 242, 302);
3343     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3344
3345     color = getPixelColor(device, 238, 388);
3346     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3347     color = getPixelColor(device, 242, 388);
3348     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3349     color = getPixelColor(device, 238, 392);
3350     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3351     color = getPixelColor(device, 242, 392);
3352     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3353
3354     color = getPixelColor(device, 478, 298);
3355     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3356     color = getPixelColor(device, 482, 298);
3357     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3358     color = getPixelColor(device, 478, 302);
3359     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3360     color = getPixelColor(device, 482, 302);
3361     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3362
3363     color = getPixelColor(device, 478, 388);
3364     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3365     color = getPixelColor(device, 482, 388);
3366     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3367     color = getPixelColor(device, 478, 392);
3368     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3369     color = getPixelColor(device, 482, 392);
3370     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3371
3372     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3373     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3374     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3375      * Thus watch out if sampling from texels between 0 and 1.
3376      */
3377     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3378     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3379        "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3380     if(!volume) {
3381         skip("Failed to create a volume texture\n");
3382         goto out;
3383     }
3384
3385     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3386     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3387     for(z = 0; z < 32; z++) {
3388         for(y = 0; y < 32; y++) {
3389             for(x = 0; x < 32; x++) {
3390                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3391                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3392                 float r_f = (float) x / 31.0;
3393                 float g_f = (float) y / 31.0;
3394                 float b_f = (float) z / 31.0;
3395
3396                 if(fmt == D3DFMT_A16B16G16R16) {
3397                     unsigned short *mem_s = mem;
3398                     mem_s[0]  = r_f * 65535.0;
3399                     mem_s[1]  = g_f * 65535.0;
3400                     mem_s[2]  = b_f * 65535.0;
3401                     mem_s[3]  = 65535;
3402                 } else {
3403                     unsigned char *mem_c = mem;
3404                     mem_c[0]  = b_f * 255.0;
3405                     mem_c[1]  = g_f * 255.0;
3406                     mem_c[2]  = r_f * 255.0;
3407                     mem_c[3]  = 255;
3408                 }
3409             }
3410         }
3411     }
3412     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3413     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3414
3415     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3416     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3417
3418     hr = IDirect3DDevice9_BeginScene(device);
3419     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3420     if(SUCCEEDED(hr))
3421     {
3422         float quad1[] = {
3423             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3424             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3425              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3426              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3427         };
3428         float quad2[] = {
3429             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3430             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3431              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3432              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3433         };
3434         float quad3[] = {
3435              0.0,       0.0,       0.1,     0.0,    0.0,
3436              0.0,       1.0,       0.1,     0.0,    0.0,
3437              1.0,       0.0,       0.1,     0.0,    0.0,
3438              1.0,       1.0,       0.1,     0.0,    0.0
3439         };
3440         float quad4[] = {
3441              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3442              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3443              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3444              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3445         };
3446         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3447                          0.0, 0.0, 1.0, 0.0,
3448                          0.0, 1.0, 0.0, 0.0,
3449                          0.0, 0.0, 0.0, 1.0};
3450         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3451         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3452
3453         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3454          * values
3455          */
3456         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3457         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3458         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3459         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3460         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3461         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3462
3463         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3464          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3465          * otherwise the w will be missing(blue).
3466          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3467          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3468          */
3469         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3470         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3471         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3472         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3473
3474         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3475         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3476         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3477         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3478         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3479         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3480         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3481         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3482         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3483
3484         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3485          * disable. ATI extends it up to the amount of values needed for the volume texture
3486          */
3487         memset(mat, 0, sizeof(mat));
3488         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3489         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3490         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3491         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3492         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3493         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3495         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3496
3497         hr = IDirect3DDevice9_EndScene(device);
3498         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3499     }
3500     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3501     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3502
3503     color = getPixelColor(device, 160, 360);
3504     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3505     color = getPixelColor(device, 160, 120);
3506     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3507        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3508     color = getPixelColor(device, 480, 120);
3509     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3510     color = getPixelColor(device, 480, 360);
3511     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3512
3513     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3514     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3515     hr = IDirect3DDevice9_BeginScene(device);
3516     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3517     if(SUCCEEDED(hr))
3518     {
3519         float quad1[] = {
3520             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3521             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3522              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3523              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3524         };
3525         float quad2[] = {
3526             -1.0,       0.0,       0.1,
3527             -1.0,       1.0,       0.1,
3528              0.0,       0.0,       0.1,
3529              0.0,       1.0,       0.1,
3530         };
3531         float quad3[] = {
3532              0.0,       0.0,       0.1,     1.0,
3533              0.0,       1.0,       0.1,     1.0,
3534              1.0,       0.0,       0.1,     1.0,
3535              1.0,       1.0,       0.1,     1.0
3536         };
3537         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3538                            0.0, 0.0, 0.0, 0.0,
3539                            0.0, 0.0, 0.0, 0.0,
3540                            0.0, 1.0, 0.0, 0.0};
3541         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3542                            1.0, 0.0, 0.0, 0.0,
3543                            0.0, 1.0, 0.0, 0.0,
3544                            0.0, 0.0, 1.0, 0.0};
3545         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3546         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3547
3548         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3549          */
3550         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3551         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3552         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3553         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3554         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3555         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3556
3557         /* None passed */
3558         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3559         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3560         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3561         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3563         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3564
3565         /* 4 used, 1 passed */
3566         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3567         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3568         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3569         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3570         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3571         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3572
3573         hr = IDirect3DDevice9_EndScene(device);
3574         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3575     }
3576     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3577     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3578     color = getPixelColor(device, 160, 360);
3579     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3580     color = getPixelColor(device, 160, 120);
3581     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3582     color = getPixelColor(device, 480, 120);
3583     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3584     /* Quad4: unused */
3585
3586     IDirect3DVolumeTexture9_Release(volume);
3587
3588     out:
3589     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3590     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3591     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3592     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3593     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3594     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3595     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3596     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3597     IDirect3DVertexDeclaration9_Release(decl);
3598     IDirect3DVertexDeclaration9_Release(decl2);
3599     IDirect3DVertexDeclaration9_Release(decl3);
3600 }
3601
3602 static void texdepth_test(IDirect3DDevice9 *device)
3603 {
3604     IDirect3DPixelShader9 *shader;
3605     HRESULT hr;
3606     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3607     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3608     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3609     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3610     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3611     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3612     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3613     DWORD shader_code[] = {
3614         0xffff0104,                                                                 /* ps_1_4               */
3615         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3616         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3617         0x0000fffd,                                                                 /* phase                */
3618         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3619         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3620         0x0000ffff                                                                  /* end                  */
3621     };
3622     DWORD color;
3623     float vertex[] = {
3624        -1.0,   -1.0,    0.0,
3625         1.0,   -1.0,    1.0,
3626        -1.0,    1.0,    0.0,
3627         1.0,    1.0,    1.0
3628     };
3629
3630     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3631     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3632
3633     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3634     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3635     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3636     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3637     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3638     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3639     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3640     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3641     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3642
3643     /* Fill the depth buffer with a gradient */
3644     hr = IDirect3DDevice9_BeginScene(device);
3645     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3646     if(SUCCEEDED(hr))
3647     {
3648         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3649         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3650         hr = IDirect3DDevice9_EndScene(device);
3651         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3652     }
3653
3654     /* Now perform the actual tests. Same geometry, but with the shader */
3655     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3656     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3657     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3658     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3659     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3660     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3661
3662     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3663     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3664     hr = IDirect3DDevice9_BeginScene(device);
3665     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3666     if(SUCCEEDED(hr))
3667     {
3668         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3669         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3670
3671         hr = IDirect3DDevice9_EndScene(device);
3672         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3673     }
3674
3675     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3676     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3677     color = getPixelColor(device, 158, 240);
3678     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3679     color = getPixelColor(device, 162, 240);
3680     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3681
3682     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3683
3684     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3685     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3686     hr = IDirect3DDevice9_BeginScene(device);
3687     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3688     if(SUCCEEDED(hr))
3689     {
3690         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3691         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3692
3693         hr = IDirect3DDevice9_EndScene(device);
3694         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3695     }
3696
3697     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3698     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3699     color = getPixelColor(device, 318, 240);
3700     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3701     color = getPixelColor(device, 322, 240);
3702     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3703
3704     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3705
3706     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3707     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3708     hr = IDirect3DDevice9_BeginScene(device);
3709     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3710     if(SUCCEEDED(hr))
3711     {
3712         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3713         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3714
3715         hr = IDirect3DDevice9_EndScene(device);
3716         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3717     }
3718     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3720
3721     color = getPixelColor(device, 1, 240);
3722     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3723
3724     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3725
3726     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3727     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3728     hr = IDirect3DDevice9_BeginScene(device);
3729     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3730     if(SUCCEEDED(hr))
3731     {
3732         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3733         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3734
3735         hr = IDirect3DDevice9_EndScene(device);
3736         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3737     }
3738     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3739     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3740     color = getPixelColor(device, 318, 240);
3741     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3742     color = getPixelColor(device, 322, 240);
3743     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3744
3745     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3746
3747     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3748     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3749     hr = IDirect3DDevice9_BeginScene(device);
3750     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3751     if(SUCCEEDED(hr))
3752     {
3753         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3754         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3755
3756         hr = IDirect3DDevice9_EndScene(device);
3757         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3758     }
3759     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3761
3762     color = getPixelColor(device, 1, 240);
3763     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3764
3765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3766
3767     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3768     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3769     hr = IDirect3DDevice9_BeginScene(device);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3771     if(SUCCEEDED(hr))
3772     {
3773         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3774         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3775
3776         hr = IDirect3DDevice9_EndScene(device);
3777         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3778     }
3779     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3781
3782     color = getPixelColor(device, 638, 240);
3783     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3784
3785     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3786
3787     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3788     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3789     hr = IDirect3DDevice9_BeginScene(device);
3790     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3791     if(SUCCEEDED(hr))
3792     {
3793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3794         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3795
3796         hr = IDirect3DDevice9_EndScene(device);
3797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3798     }
3799     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3801
3802     color = getPixelColor(device, 638, 240);
3803     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3804
3805     /* Cleanup */
3806     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3808     IDirect3DPixelShader9_Release(shader);
3809
3810     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3811     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3812     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3813     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3814 }
3815
3816 static void texkill_test(IDirect3DDevice9 *device)
3817 {
3818     IDirect3DPixelShader9 *shader;
3819     HRESULT hr;
3820     DWORD color;
3821
3822     const float vertex[] = {
3823     /*                          bottom  top    right    left */
3824         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3825          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3826         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3827          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3828     };
3829
3830     DWORD shader_code_11[] = {
3831     0xffff0101,                                                             /* ps_1_1                     */
3832     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3833     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3834     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3835     0x0000ffff                                                              /* end                        */
3836     };
3837     DWORD shader_code_20[] = {
3838     0xffff0200,                                                             /* ps_2_0                     */
3839     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3840     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3841     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3842     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3843     0x0000ffff                                                              /* end                        */
3844     };
3845
3846     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3847     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3848     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3849     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3850
3851     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3852     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3853     hr = IDirect3DDevice9_BeginScene(device);
3854     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3855     if(SUCCEEDED(hr))
3856     {
3857         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3858         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3859         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3860         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3861         hr = IDirect3DDevice9_EndScene(device);
3862         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3863     }
3864     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3865     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3866     color = getPixelColor(device, 63, 46);
3867     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3868     color = getPixelColor(device, 66, 46);
3869     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3870     color = getPixelColor(device, 63, 49);
3871     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3872     color = getPixelColor(device, 66, 49);
3873     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3874
3875     color = getPixelColor(device, 578, 46);
3876     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3877     color = getPixelColor(device, 575, 46);
3878     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3879     color = getPixelColor(device, 578, 49);
3880     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3881     color = getPixelColor(device, 575, 49);
3882     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3883
3884     color = getPixelColor(device, 63, 430);
3885     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3886     color = getPixelColor(device, 63, 433);
3887     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3888     color = getPixelColor(device, 66, 433);
3889     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3890     color = getPixelColor(device, 66, 430);
3891     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3892
3893     color = getPixelColor(device, 578, 430);
3894     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3895     color = getPixelColor(device, 578, 433);
3896     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3897     color = getPixelColor(device, 575, 433);
3898     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3899     color = getPixelColor(device, 575, 430);
3900     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3901
3902     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3903     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3904     IDirect3DPixelShader9_Release(shader);
3905
3906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3907     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3908     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3909     if(FAILED(hr)) {
3910         skip("Failed to create 2.0 test shader, most likely not supported\n");
3911         return;
3912     }
3913
3914     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3915     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3916     hr = IDirect3DDevice9_BeginScene(device);
3917     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3918     if(SUCCEEDED(hr))
3919     {
3920         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3921         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3922         hr = IDirect3DDevice9_EndScene(device);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3924     }
3925     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3926
3927     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3928     color = getPixelColor(device, 63, 46);
3929     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3930     color = getPixelColor(device, 66, 46);
3931     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3932     color = getPixelColor(device, 63, 49);
3933     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3934     color = getPixelColor(device, 66, 49);
3935     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3936
3937     color = getPixelColor(device, 578, 46);
3938     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3939     color = getPixelColor(device, 575, 46);
3940     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3941     color = getPixelColor(device, 578, 49);
3942     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3943     color = getPixelColor(device, 575, 49);
3944     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3945
3946     color = getPixelColor(device, 63, 430);
3947     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3948     color = getPixelColor(device, 63, 433);
3949     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3950     color = getPixelColor(device, 66, 433);
3951     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3952     color = getPixelColor(device, 66, 430);
3953     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3954
3955     color = getPixelColor(device, 578, 430);
3956     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3957     color = getPixelColor(device, 578, 433);
3958     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3959     color = getPixelColor(device, 575, 433);
3960     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3961     color = getPixelColor(device, 575, 430);
3962     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3963
3964     /* Cleanup */
3965     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3966     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3967     IDirect3DPixelShader9_Release(shader);
3968 }
3969
3970 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3971 {
3972     IDirect3D9 *d3d9;
3973     HRESULT hr;
3974     IDirect3DTexture9 *texture;
3975     IDirect3DPixelShader9 *shader;
3976     IDirect3DPixelShader9 *shader2;
3977     D3DLOCKED_RECT lr;
3978     DWORD color;
3979     DWORD shader_code[] = {
3980         0xffff0101,                             /* ps_1_1       */
3981         0x00000042, 0xb00f0000,                 /* tex t0       */
3982         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3983         0x0000ffff                              /* end          */
3984     };
3985     DWORD shader_code2[] = {
3986         0xffff0101,                             /* ps_1_1       */
3987         0x00000042, 0xb00f0000,                 /* tex t0       */
3988         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3989         0x0000ffff                              /* end          */
3990     };
3991
3992     float quad[] = {
3993        -1.0,   -1.0,   0.1,     0.5,    0.5,
3994         1.0,   -1.0,   0.1,     0.5,    0.5,
3995        -1.0,    1.0,   0.1,     0.5,    0.5,
3996         1.0,    1.0,   0.1,     0.5,    0.5,
3997     };
3998
3999     memset(&lr, 0, sizeof(lr));
4000     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4001     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4002                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4003     IDirect3D9_Release(d3d9);
4004     if(FAILED(hr)) {
4005         skip("No D3DFMT_X8L8V8U8 support\n");
4006     };
4007
4008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4009     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4010
4011     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4012     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4013     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4014     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4015     *((DWORD *) lr.pBits) = 0x11ca3141;
4016     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4017     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4018
4019     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4020     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4021     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4022     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4023
4024     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4025     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4026     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4027     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4028     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4030
4031     hr = IDirect3DDevice9_BeginScene(device);
4032     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4033     if(SUCCEEDED(hr))
4034     {
4035         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4036         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4037
4038         hr = IDirect3DDevice9_EndScene(device);
4039         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4040     }
4041     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4042     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4043     color = getPixelColor(device, 578, 430);
4044     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4045        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4046
4047     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4048     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4049     hr = IDirect3DDevice9_BeginScene(device);
4050     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4051     if(SUCCEEDED(hr))
4052     {
4053         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4054         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4055
4056         hr = IDirect3DDevice9_EndScene(device);
4057         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4058     }
4059     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4060     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4061     color = getPixelColor(device, 578, 430);
4062     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4063
4064     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4065     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4066     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4067     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4068     IDirect3DPixelShader9_Release(shader);
4069     IDirect3DPixelShader9_Release(shader2);
4070     IDirect3DTexture9_Release(texture);
4071 }
4072
4073 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4074 {
4075     HRESULT hr;
4076     IDirect3D9 *d3d;
4077     IDirect3DTexture9 *texture = NULL;
4078     IDirect3DSurface9 *surface;
4079     DWORD color;
4080     const RECT r1 = {256, 256, 512, 512};
4081     const RECT r2 = {512, 256, 768, 512};
4082     const RECT r3 = {256, 512, 512, 768};
4083     const RECT r4 = {512, 512, 768, 768};
4084     unsigned int x, y;
4085     D3DLOCKED_RECT lr;
4086     memset(&lr, 0, sizeof(lr));
4087
4088     IDirect3DDevice9_GetDirect3D(device, &d3d);
4089     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4090        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4091         skip("No autogenmipmap support\n");
4092         IDirect3D9_Release(d3d);
4093         return;
4094     }
4095     IDirect3D9_Release(d3d);
4096
4097     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4098     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4099
4100     /* Make the mipmap big, so that a smaller mipmap is used
4101      */
4102     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4103                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4105
4106     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4107     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4108     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4109     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4110     for(y = 0; y < 1024; y++) {
4111         for(x = 0; x < 1024; x++) {
4112             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4113             POINT pt;
4114
4115             pt.x = x;
4116             pt.y = y;
4117             if(PtInRect(&r1, pt)) {
4118                 *dst = 0xffff0000;
4119             } else if(PtInRect(&r2, pt)) {
4120                 *dst = 0xff00ff00;
4121             } else if(PtInRect(&r3, pt)) {
4122                 *dst = 0xff0000ff;
4123             } else if(PtInRect(&r4, pt)) {
4124                 *dst = 0xff000000;
4125             } else {
4126                 *dst = 0xffffffff;
4127             }
4128         }
4129     }
4130     hr = IDirect3DSurface9_UnlockRect(surface);
4131     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4132     IDirect3DSurface9_Release(surface);
4133
4134     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4135     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4136     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4137     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4138
4139     hr = IDirect3DDevice9_BeginScene(device);
4140     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4141     if(SUCCEEDED(hr)) {
4142         const float quad[] =  {
4143            -0.5,   -0.5,    0.1,    0.0,    0.0,
4144            -0.5,    0.5,    0.1,    0.0,    1.0,
4145             0.5,   -0.5,    0.1,    1.0,    0.0,
4146             0.5,    0.5,    0.1,    1.0,    1.0
4147         };
4148
4149         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4150         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4152         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4153         hr = IDirect3DDevice9_EndScene(device);
4154         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4155     }
4156     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4157     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4158     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4159     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4160     IDirect3DTexture9_Release(texture);
4161
4162     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4163     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4164     color = getPixelColor(device, 200, 200);
4165     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4166     color = getPixelColor(device, 280, 200);
4167     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4168     color = getPixelColor(device, 360, 200);
4169     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4170     color = getPixelColor(device, 440, 200);
4171     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4172     color = getPixelColor(device, 200, 270);
4173     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4174     color = getPixelColor(device, 280, 270);
4175     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4176     color = getPixelColor(device, 360, 270);
4177     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4178     color = getPixelColor(device, 440, 270);
4179     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4180 }
4181
4182 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4183 {
4184     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4185     IDirect3DVertexDeclaration9 *decl;
4186     HRESULT hr;
4187     DWORD color;
4188     DWORD shader_code_11[] =  {
4189         0xfffe0101,                                         /* vs_1_1           */
4190         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4191         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4192         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4193         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4194         0x0000ffff                                          /* end              */
4195     };
4196     DWORD shader_code_11_2[] =  {
4197         0xfffe0101,                                         /* vs_1_1           */
4198         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4199         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4200         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4201         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4202         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4203         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4204         0x0000ffff                                          /* end              */
4205     };
4206     DWORD shader_code_20[] =  {
4207         0xfffe0200,                                         /* vs_2_0           */
4208         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4209         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4210         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4211         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4212         0x0000ffff                                          /* end              */
4213     };
4214     DWORD shader_code_20_2[] =  {
4215         0xfffe0200,                                         /* vs_2_0           */
4216         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4217         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4218         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4219         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4220         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4221         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4222         0x0000ffff                                          /* end              */
4223     };
4224     static const D3DVERTEXELEMENT9 decl_elements[] = {
4225         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4226         D3DDECL_END()
4227     };
4228     float quad1[] = {
4229         -1.0,   -1.0,   0.1,
4230          0.0,   -1.0,   0.1,
4231         -1.0,    0.0,   0.1,
4232          0.0,    0.0,   0.1
4233     };
4234     float quad2[] = {
4235          0.0,   -1.0,   0.1,
4236          1.0,   -1.0,   0.1,
4237          0.0,    0.0,   0.1,
4238          1.0,    0.0,   0.1
4239     };
4240     float quad3[] = {
4241          0.0,    0.0,   0.1,
4242          1.0,    0.0,   0.1,
4243          0.0,    1.0,   0.1,
4244          1.0,    1.0,   0.1
4245     };
4246     float quad4[] = {
4247         -1.0,    0.0,   0.1,
4248          0.0,    0.0,   0.1,
4249         -1.0,    1.0,   0.1,
4250          0.0,    1.0,   0.1
4251     };
4252     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4253     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4254
4255     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4256     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4257
4258     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4259     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4260     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4262     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4263     if(FAILED(hr)) shader_20 = NULL;
4264     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4265     if(FAILED(hr)) shader_20_2 = NULL;
4266     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4268
4269     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4270     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4271     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4272     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4273     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4274     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4275
4276     hr = IDirect3DDevice9_BeginScene(device);
4277     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4278     if(SUCCEEDED(hr))
4279     {
4280         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4281         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4283         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4284
4285         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4286         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4287         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4288         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4289
4290         if(shader_20) {
4291             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4292             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4293             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4294             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4295         }
4296
4297         if(shader_20_2) {
4298             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4299             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4300             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4301             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4302         }
4303
4304         hr = IDirect3DDevice9_EndScene(device);
4305         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4306     }
4307     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4308     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4309
4310     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4311     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4312     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4313     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4314
4315     color = getPixelColor(device, 160, 360);
4316     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4317        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4318     color = getPixelColor(device, 480, 360);
4319     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4320        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4321     if(shader_20) {
4322         color = getPixelColor(device, 160, 120);
4323         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4324            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4325     }
4326     if(shader_20_2) {
4327         color = getPixelColor(device, 480, 120);
4328         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4330     }
4331
4332     IDirect3DVertexDeclaration9_Release(decl);
4333     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4334     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4335     IDirect3DVertexShader9_Release(shader_11_2);
4336     IDirect3DVertexShader9_Release(shader_11);
4337 }
4338
4339 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4340 {
4341     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4342     HRESULT hr;
4343     DWORD color;
4344     DWORD shader_code_11[] =  {
4345         0xffff0101,                                         /* ps_1_1           */
4346         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4347         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4348         0x0000ffff                                          /* end              */
4349     };
4350     DWORD shader_code_12[] =  {
4351         0xffff0102,                                         /* ps_1_2           */
4352         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4353         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4354         0x0000ffff                                          /* end              */
4355     };
4356     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4357      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4358      * During development of this test, 1.3 shaders were verified too
4359      */
4360     DWORD shader_code_14[] =  {
4361         0xffff0104,                                         /* ps_1_4           */
4362         /* Try to make one constant local. It gets clamped too, although the binary contains
4363          * the bigger numbers
4364          */
4365         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4366         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4367         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4368         0x0000ffff                                          /* end              */
4369     };
4370     DWORD shader_code_20[] =  {
4371         0xffff0200,                                         /* ps_2_0           */
4372         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4373         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4374         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4375         0x0000ffff                                          /* end              */
4376     };
4377     float quad1[] = {
4378         -1.0,   -1.0,   0.1,
4379          0.0,   -1.0,   0.1,
4380         -1.0,    0.0,   0.1,
4381          0.0,    0.0,   0.1
4382     };
4383     float quad2[] = {
4384          0.0,   -1.0,   0.1,
4385          1.0,   -1.0,   0.1,
4386          0.0,    0.0,   0.1,
4387          1.0,    0.0,   0.1
4388     };
4389     float quad3[] = {
4390          0.0,    0.0,   0.1,
4391          1.0,    0.0,   0.1,
4392          0.0,    1.0,   0.1,
4393          1.0,    1.0,   0.1
4394     };
4395     float quad4[] = {
4396         -1.0,    0.0,   0.1,
4397          0.0,    0.0,   0.1,
4398         -1.0,    1.0,   0.1,
4399          0.0,    1.0,   0.1
4400     };
4401     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4402     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4403
4404     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4405     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4406
4407     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4408     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4409     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4410     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4411     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4412     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4413     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4414     if(FAILED(hr)) shader_20 = NULL;
4415
4416     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4417     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4418     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4419     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4420     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4421     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4422
4423     hr = IDirect3DDevice9_BeginScene(device);
4424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4425     if(SUCCEEDED(hr))
4426     {
4427         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4428         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4429         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4430         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4431
4432         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4433         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4435         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4436
4437         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4438         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4439         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4440         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4441
4442         if(shader_20) {
4443             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4444             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4445             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4446             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4447         }
4448
4449         hr = IDirect3DDevice9_EndScene(device);
4450         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4451     }
4452     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4453     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4454
4455     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4456     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4457
4458     color = getPixelColor(device, 160, 360);
4459     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4460        "quad 1 has color %08x, expected 0x00808000\n", color);
4461     color = getPixelColor(device, 480, 360);
4462     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4463        "quad 2 has color %08x, expected 0x00808000\n", color);
4464     color = getPixelColor(device, 480, 120);
4465     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4466        "quad 3 has color %08x, expected 0x00808000\n", color);
4467     if(shader_20) {
4468         color = getPixelColor(device, 160, 120);
4469         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4470            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4471     }
4472
4473     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4474     IDirect3DPixelShader9_Release(shader_14);
4475     IDirect3DPixelShader9_Release(shader_12);
4476     IDirect3DPixelShader9_Release(shader_11);
4477 }
4478
4479 static void dp2add_ps_test(IDirect3DDevice9 *device)
4480 {
4481     IDirect3DPixelShader9 *shader_dp2add = NULL;
4482     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4483     HRESULT hr;
4484     DWORD color;
4485
4486     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4487      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4488      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4489      * r0 first.
4490      * The result here for the r,g,b components should be roughly 0.5:
4491      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4492     static const DWORD shader_code_dp2add[] =  {
4493         0xffff0200,                                                             /* ps_2_0                       */
4494         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4495
4496         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4497         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4498
4499         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4500         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4501         0x0000ffff                                                              /* end                          */
4502     };
4503
4504     /* Test the _sat modifier, too.  Result here should be:
4505      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4506      *      _SAT: ==> 1.0
4507      *   ADD: (1.0 + -0.5) = 0.5
4508      */
4509     static const DWORD shader_code_dp2add_sat[] =  {
4510         0xffff0200,                                                             /* ps_2_0                           */
4511         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4512
4513         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4514         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4515         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4516
4517         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4518         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4519         0x0000ffff                                                              /* end                              */
4520     };
4521
4522     const float quad[] = {
4523         -1.0,   -1.0,   0.1,
4524          1.0,   -1.0,   0.1,
4525         -1.0,    1.0,   0.1,
4526          1.0,    1.0,   0.1
4527     };
4528
4529
4530     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4531     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4532
4533     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4534     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4535
4536     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4537     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4538
4539     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4541
4542     if (shader_dp2add) {
4543
4544         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4545         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4546
4547         hr = IDirect3DDevice9_BeginScene(device);
4548         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4549         if(SUCCEEDED(hr))
4550         {
4551             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4552             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4553
4554             hr = IDirect3DDevice9_EndScene(device);
4555             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4556         }
4557         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4558         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4559
4560         color = getPixelColor(device, 360, 240);
4561         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4562
4563         IDirect3DPixelShader9_Release(shader_dp2add);
4564     } else {
4565         skip("dp2add shader creation failed\n");
4566     }
4567
4568     if (shader_dp2add_sat) {
4569
4570         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4571         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4572
4573         hr = IDirect3DDevice9_BeginScene(device);
4574         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4575         if(SUCCEEDED(hr))
4576         {
4577             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4578             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4579
4580             hr = IDirect3DDevice9_EndScene(device);
4581             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4582         }
4583         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4584         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4585
4586         color = getPixelColor(device, 360, 240);
4587         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4588
4589         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4590     } else {
4591         skip("dp2add shader creation failed\n");
4592     }
4593
4594     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4595     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4596 }
4597
4598 static void cnd_test(IDirect3DDevice9 *device)
4599 {
4600     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4601     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4602     HRESULT hr;
4603     DWORD color;
4604     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4605      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4606      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4607      */
4608     DWORD shader_code_11[] =  {
4609         0xffff0101,                                                                 /* ps_1_1               */
4610         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4611         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4612         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4613         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4614         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4615         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4616         0x0000ffff                                                                  /* end                  */
4617     };
4618     DWORD shader_code_12[] =  {
4619         0xffff0102,                                                                 /* ps_1_2               */
4620         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4621         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4622         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4623         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4624         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4625         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4626         0x0000ffff                                                                  /* end                  */
4627     };
4628     DWORD shader_code_13[] =  {
4629         0xffff0103,                                                                 /* ps_1_3               */
4630         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4631         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4632         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4633         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4634         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4635         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4636         0x0000ffff                                                                  /* end                  */
4637     };
4638     DWORD shader_code_14[] =  {
4639         0xffff0104,                                                                 /* ps_1_3               */
4640         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4641         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4642         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4643         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4644         0x0000ffff                                                                  /* end                  */
4645     };
4646
4647     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4648      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4649      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4650      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4651      * native CreatePixelShader returns an error.
4652      *
4653      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4654      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4655      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4656      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4657      */
4658     DWORD shader_code_11_coissue[] =  {
4659         0xffff0101,                                                             /* ps_1_1                   */
4660         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4661         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4662         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4663         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4664         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4665         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4666         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4667         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4668         /* 0x40000000 = D3DSI_COISSUE */
4669         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4670         0x0000ffff                                                              /* end                      */
4671     };
4672     DWORD shader_code_12_coissue[] =  {
4673         0xffff0102,                                                             /* ps_1_2                   */
4674         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4675         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4676         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4677         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4678         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4679         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4680         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4681         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4682         /* 0x40000000 = D3DSI_COISSUE */
4683         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4684         0x0000ffff                                                              /* end                      */
4685     };
4686     DWORD shader_code_13_coissue[] =  {
4687         0xffff0103,                                                             /* ps_1_3                   */
4688         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4689         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4690         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4691         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4692         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4693         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4694         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4695         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4696         /* 0x40000000 = D3DSI_COISSUE */
4697         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4698         0x0000ffff                                                              /* end                      */
4699     };
4700     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4701      * compare against 0.5
4702      */
4703     DWORD shader_code_14_coissue[] =  {
4704         0xffff0104,                                                             /* ps_1_4                   */
4705         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4706         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4707         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4708         /* 0x40000000 = D3DSI_COISSUE */
4709         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4710         0x0000ffff                                                              /* end                      */
4711     };
4712     float quad1[] = {
4713         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4714          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4715         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4716          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4717     };
4718     float quad2[] = {
4719          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4720          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4721          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4722          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4723     };
4724     float quad3[] = {
4725          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4726          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4727          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4728          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4729     };
4730     float quad4[] = {
4731         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4732          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4733         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4734          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4735     };
4736     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4737     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4738     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4739     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4740
4741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4742     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4743
4744     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4746     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4747     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4748     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4749     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4750     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4752     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4754     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4755     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4756     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4758     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4760
4761     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4762     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4763     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4764     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4765     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4767
4768     hr = IDirect3DDevice9_BeginScene(device);
4769     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4770     if(SUCCEEDED(hr))
4771     {
4772         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4773         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4774         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4775         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4776
4777         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4778         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4780         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4781
4782         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4784         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4785         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4786
4787         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4788         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4789         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4790         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791
4792         hr = IDirect3DDevice9_EndScene(device);
4793         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4794     }
4795     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4796     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4797
4798     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4799     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4800
4801     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4802     color = getPixelColor(device, 158, 118);
4803     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4804     color = getPixelColor(device, 162, 118);
4805     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4806     color = getPixelColor(device, 158, 122);
4807     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4808     color = getPixelColor(device, 162, 122);
4809     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4810
4811     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4812     color = getPixelColor(device, 158, 358);
4813     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4814     color = getPixelColor(device, 162, 358);
4815     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4816         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4817     color = getPixelColor(device, 158, 362);
4818     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4819     color = getPixelColor(device, 162, 362);
4820     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4821         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4822
4823     /* 1.2 shader */
4824     color = getPixelColor(device, 478, 358);
4825     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4826     color = getPixelColor(device, 482, 358);
4827     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4828         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4829     color = getPixelColor(device, 478, 362);
4830     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4831     color = getPixelColor(device, 482, 362);
4832     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4833         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4834
4835     /* 1.3 shader */
4836     color = getPixelColor(device, 478, 118);
4837     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4838     color = getPixelColor(device, 482, 118);
4839     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4840         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4841     color = getPixelColor(device, 478, 122);
4842     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4843     color = getPixelColor(device, 482, 122);
4844     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4845         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4846
4847     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4848     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4849     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4850     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4851     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4852     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4853
4854     hr = IDirect3DDevice9_BeginScene(device);
4855     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4856     if(SUCCEEDED(hr))
4857     {
4858         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4859         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4860         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4861         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4862
4863         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4864         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4866         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4867
4868         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4869         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4870         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4871         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4872
4873         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4874         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4875         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4876         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4877
4878         hr = IDirect3DDevice9_EndScene(device);
4879         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4880     }
4881     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4882     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4883
4884     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4885      * that we swapped the values in c1 and c2 to make the other tests return some color
4886      */
4887     color = getPixelColor(device, 158, 118);
4888     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4889     color = getPixelColor(device, 162, 118);
4890     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4891     color = getPixelColor(device, 158, 122);
4892     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4893     color = getPixelColor(device, 162, 122);
4894     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4895
4896     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4897     color = getPixelColor(device, 158, 358);
4898     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4899         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4900     color = getPixelColor(device, 162, 358);
4901     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4902         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4903     color = getPixelColor(device, 158, 362);
4904     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4905         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4906     color = getPixelColor(device, 162, 362);
4907     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4908         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4909
4910     /* 1.2 shader */
4911     color = getPixelColor(device, 478, 358);
4912     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4913         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4914     color = getPixelColor(device, 482, 358);
4915     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4916         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4917     color = getPixelColor(device, 478, 362);
4918     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4919         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4920     color = getPixelColor(device, 482, 362);
4921     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4922         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4923
4924     /* 1.3 shader */
4925     color = getPixelColor(device, 478, 118);
4926     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4927         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4928     color = getPixelColor(device, 482, 118);
4929     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4930         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4931     color = getPixelColor(device, 478, 122);
4932     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4933         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4934     color = getPixelColor(device, 482, 122);
4935     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4936         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4937
4938     IDirect3DPixelShader9_Release(shader_14_coissue);
4939     IDirect3DPixelShader9_Release(shader_13_coissue);
4940     IDirect3DPixelShader9_Release(shader_12_coissue);
4941     IDirect3DPixelShader9_Release(shader_11_coissue);
4942     IDirect3DPixelShader9_Release(shader_14);
4943     IDirect3DPixelShader9_Release(shader_13);
4944     IDirect3DPixelShader9_Release(shader_12);
4945     IDirect3DPixelShader9_Release(shader_11);
4946 }
4947
4948 static void nested_loop_test(IDirect3DDevice9 *device) {
4949     const DWORD shader_code[] = {
4950         0xffff0300,                                                             /* ps_3_0               */
4951         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4952         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4953         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4954         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4955         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4956         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4957         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4958         0x0000001d,                                                             /* endloop              */
4959         0x0000001d,                                                             /* endloop              */
4960         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4961         0x0000ffff                                                              /* end                  */
4962     };
4963     IDirect3DPixelShader9 *shader;
4964     HRESULT hr;
4965     DWORD color;
4966     const float quad[] = {
4967         -1.0,   -1.0,   0.1,
4968          1.0,   -1.0,   0.1,
4969         -1.0,    1.0,   0.1,
4970          1.0,    1.0,   0.1
4971     };
4972
4973     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4974     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4975     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4976     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4977     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4978     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4979     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4980     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4981
4982     hr = IDirect3DDevice9_BeginScene(device);
4983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4984     if(SUCCEEDED(hr))
4985     {
4986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4988         hr = IDirect3DDevice9_EndScene(device);
4989         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4990     }
4991     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4992     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4993
4994     color = getPixelColor(device, 360, 240);
4995     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4996        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4997
4998     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4999     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
5000     IDirect3DPixelShader9_Release(shader);
5001 }
5002
5003 struct varying_test_struct
5004 {
5005     const DWORD             *shader_code;
5006     IDirect3DPixelShader9   *shader;
5007     DWORD                   color, color_rhw;
5008     const char              *name;
5009     BOOL                    todo, todo_rhw;
5010 };
5011
5012 struct hugeVertex
5013 {
5014     float pos_x,        pos_y,      pos_z,      rhw;
5015     float weight_1,     weight_2,   weight_3,   weight_4;
5016     float index_1,      index_2,    index_3,    index_4;
5017     float normal_1,     normal_2,   normal_3,   normal_4;
5018     float fog_1,        fog_2,      fog_3,      fog_4;
5019     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5020     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5021     float binormal_1,   binormal_2, binormal_3, binormal_4;
5022     float depth_1,      depth_2,    depth_3,    depth_4;
5023     DWORD diffuse, specular;
5024 };
5025
5026 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5027     /* dcl_position: fails to compile */
5028     const DWORD blendweight_code[] = {
5029         0xffff0300,                             /* ps_3_0                   */
5030         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5031         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5032         0x0000ffff                              /* end                      */
5033     };
5034     const DWORD blendindices_code[] = {
5035         0xffff0300,                             /* ps_3_0                   */
5036         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5037         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5038         0x0000ffff                              /* end                      */
5039     };
5040     const DWORD normal_code[] = {
5041         0xffff0300,                             /* ps_3_0                   */
5042         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5043         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5044         0x0000ffff                              /* end                      */
5045     };
5046     /* psize: fails? */
5047     const DWORD texcoord0_code[] = {
5048         0xffff0300,                             /* ps_3_0                   */
5049         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5050         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5051         0x0000ffff                              /* end                      */
5052     };
5053     const DWORD tangent_code[] = {
5054         0xffff0300,                             /* ps_3_0                   */
5055         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5056         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5057         0x0000ffff                              /* end                      */
5058     };
5059     const DWORD binormal_code[] = {
5060         0xffff0300,                             /* ps_3_0                   */
5061         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5062         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5063         0x0000ffff                              /* end                      */
5064     };
5065     /* tessfactor: fails */
5066     /* positiont: fails */
5067     const DWORD color_code[] = {
5068         0xffff0300,                             /* ps_3_0                   */
5069         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5070         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5071         0x0000ffff                              /* end                      */
5072     };
5073     const DWORD fog_code[] = {
5074         0xffff0300,                             /* ps_3_0                   */
5075         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5076         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5077         0x0000ffff                              /* end                      */
5078     };
5079     const DWORD depth_code[] = {
5080         0xffff0300,                             /* ps_3_0                   */
5081         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5082         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5083         0x0000ffff                              /* end                      */
5084     };
5085     const DWORD specular_code[] = {
5086         0xffff0300,                             /* ps_3_0                   */
5087         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5088         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5089         0x0000ffff                              /* end                      */
5090     };
5091     /* sample: fails */
5092
5093     struct varying_test_struct tests[] = {
5094        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5095        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5096        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5097        /* Why does dx not forward the texcoord? */
5098        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5099        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5100        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5101        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5102        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5103        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5104        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5105     };
5106     /* Declare a monster vertex type :-) */
5107     static const D3DVERTEXELEMENT9 decl_elements[] = {
5108         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5109         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5110         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5111         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5112         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5113         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5114         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5115         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5116         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5117         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5118         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5119         D3DDECL_END()
5120     };
5121     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5122         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5123         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5124         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5125         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5126         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5127         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5128         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5129         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5130         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5131         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5132         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5133         D3DDECL_END()
5134     };
5135     struct hugeVertex data[4] = {
5136         {
5137             -1.0,   -1.0,   0.1,    1.0,
5138              0.1,    0.1,   0.1,    0.1,
5139              0.2,    0.2,   0.2,    0.2,
5140              0.3,    0.3,   0.3,    0.3,
5141              0.4,    0.4,   0.4,    0.4,
5142              0.50,   0.55,  0.55,   0.55,
5143              0.6,    0.6,   0.6,    0.7,
5144              0.7,    0.7,   0.7,    0.6,
5145              0.8,    0.8,   0.8,    0.8,
5146              0xe6e6e6e6, /* 0.9 * 256 */
5147              0x224488ff  /* Nothing special */
5148         },
5149         {
5150              1.0,   -1.0,   0.1,    1.0,
5151              0.1,    0.1,   0.1,    0.1,
5152              0.2,    0.2,   0.2,    0.2,
5153              0.3,    0.3,   0.3,    0.3,
5154              0.4,    0.4,   0.4,    0.4,
5155              0.50,   0.55,  0.55,   0.55,
5156              0.6,    0.6,   0.6,    0.7,
5157              0.7,    0.7,   0.7,    0.6,
5158              0.8,    0.8,   0.8,    0.8,
5159              0xe6e6e6e6, /* 0.9 * 256 */
5160              0x224488ff /* Nothing special */
5161         },
5162         {
5163             -1.0,    1.0,   0.1,    1.0,
5164              0.1,    0.1,   0.1,    0.1,
5165              0.2,    0.2,   0.2,    0.2,
5166              0.3,    0.3,   0.3,    0.3,
5167              0.4,    0.4,   0.4,    0.4,
5168              0.50,   0.55,  0.55,   0.55,
5169              0.6,    0.6,   0.6,    0.7,
5170              0.7,    0.7,   0.7,    0.6,
5171              0.8,    0.8,   0.8,    0.8,
5172              0xe6e6e6e6, /* 0.9 * 256 */
5173              0x224488ff /* Nothing special */
5174         },
5175         {
5176              1.0,    1.0,   0.1,    1.0,
5177              0.1,    0.1,   0.1,    0.1,
5178              0.2,    0.2,   0.2,    0.2,
5179              0.3,    0.3,   0.3,    0.3,
5180              0.4,    0.4,   0.4,    0.4,
5181              0.50,   0.55,  0.55,   0.55,
5182              0.6,    0.6,   0.6,    0.7,
5183              0.7,    0.7,   0.7,    0.6,
5184              0.8,    0.8,   0.8,    0.8,
5185              0xe6e6e6e6, /* 0.9 * 256 */
5186              0x224488ff /* Nothing special */
5187         },
5188     };
5189     struct hugeVertex data2[4];
5190     IDirect3DVertexDeclaration9 *decl;
5191     IDirect3DVertexDeclaration9 *decl2;
5192     HRESULT hr;
5193     unsigned int i;
5194     DWORD color, r, g, b, r_e, g_e, b_e;
5195     BOOL drawok;
5196
5197     memcpy(data2, data, sizeof(data2));
5198     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5199     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5200     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5201     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5202
5203     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5205     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5207     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5208     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5209
5210     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5211     {
5212         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5213         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5214            tests[i].name, DXGetErrorString9(hr));
5215     }
5216
5217     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5218     {
5219         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5220         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5221
5222         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5223         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5224
5225         hr = IDirect3DDevice9_BeginScene(device);
5226         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5227         drawok = FALSE;
5228         if(SUCCEEDED(hr))
5229         {
5230             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5231             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5232             drawok = SUCCEEDED(hr);
5233             hr = IDirect3DDevice9_EndScene(device);
5234             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5235         }
5236         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5237         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5238
5239         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5240          * the failure and do not check the color if it failed
5241          */
5242         if(!drawok) {
5243             continue;
5244         }
5245
5246         color = getPixelColor(device, 360, 240);
5247         r = color & 0x00ff0000 >> 16;
5248         g = color & 0x0000ff00 >>  8;
5249         b = color & 0x000000ff;
5250         r_e = tests[i].color & 0x00ff0000 >> 16;
5251         g_e = tests[i].color & 0x0000ff00 >>  8;
5252         b_e = tests[i].color & 0x000000ff;
5253
5254         if(tests[i].todo) {
5255             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5256                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5257                          tests[i].name, color, tests[i].color);
5258         } else {
5259             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5260                "Test %s returned color 0x%08x, expected 0x%08x\n",
5261                tests[i].name, color, tests[i].color);
5262         }
5263     }
5264
5265     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5266     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5267     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5268     {
5269         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5270         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5271
5272         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5273         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5274
5275         hr = IDirect3DDevice9_BeginScene(device);
5276         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5277         if(SUCCEEDED(hr))
5278         {
5279             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5280             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5281             hr = IDirect3DDevice9_EndScene(device);
5282             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5283         }
5284         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5285         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5286
5287         color = getPixelColor(device, 360, 240);
5288         r = color & 0x00ff0000 >> 16;
5289         g = color & 0x0000ff00 >>  8;
5290         b = color & 0x000000ff;
5291         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5292         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5293         b_e = tests[i].color_rhw & 0x000000ff;
5294
5295         if(tests[i].todo_rhw) {
5296             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5297              * pipeline
5298              */
5299             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5300                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5301                          tests[i].name, color, tests[i].color_rhw);
5302         } else {
5303             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5304                "Test %s returned color 0x%08x, expected 0x%08x\n",
5305                tests[i].name, color, tests[i].color_rhw);
5306         }
5307     }
5308
5309     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5310     {
5311         IDirect3DPixelShader9_Release(tests[i].shader);
5312     }
5313
5314     IDirect3DVertexDeclaration9_Release(decl2);
5315     IDirect3DVertexDeclaration9_Release(decl);
5316 }
5317
5318 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5319     static const DWORD ps_code[] = {
5320     0xffff0300,                                                             /* ps_3_0                       */
5321     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5322     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5323     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5324     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5325     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5326     0x0200001f, 0x80000003, 0x900f0006,
5327     0x0200001f, 0x80000006, 0x900f0007,
5328     0x0200001f, 0x80000001, 0x900f0008,
5329     0x0200001f, 0x8000000c, 0x900f0009,
5330
5331     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5332     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5333     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5334     0x0000001d,                                                             /* endloop                      */
5335     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5336     0x0000ffff                                                              /* end                          */
5337     };
5338     static const DWORD vs_1_code[] = {
5339     0xfffe0101,                                                             /* vs_1_1                       */
5340     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5341     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5342     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5343     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5344     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5345     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5346     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5347     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5348     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5349     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5350     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5351     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5352     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5353     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5354     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5355     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5356     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5357     0x0000ffff
5358     };
5359     DWORD vs_2_code[] = {
5360     0xfffe0200,                                                             /* vs_2_0                       */
5361     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5362     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
5363     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0   */
5364     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0   */
5365     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5366     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5367     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5368     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5369     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5370     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5371     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5372     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5373     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5374     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5375     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5376     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5377     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5378     0x0000ffff                                                              /* end                          */
5379     };
5380     /* TODO: Define normal, tangent, blendweight and depth here */
5381     static const DWORD vs_3_code[] = {
5382     0xfffe0300,                                                             /* vs_3_0                       */
5383     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5384     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5385     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5386     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5387     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5388     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5389     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5390     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5391     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5392     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5393     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5394     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5395     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5396     0x0000ffff                                                              /* end                          */
5397     };
5398     float quad1[] =  {
5399         -1.0,   -1.0,   0.1,
5400          0.0,   -1.0,   0.1,
5401         -1.0,    0.0,   0.1,
5402          0.0,    0.0,   0.1
5403     };
5404     float quad2[] =  {
5405          0.0,   -1.0,   0.1,
5406          1.0,   -1.0,   0.1,
5407          0.0,    0.0,   0.1,
5408          1.0,    0.0,   0.1
5409     };
5410     float quad3[] =  {
5411         -1.0,    0.0,   0.1,
5412          0.0,    0.0,   0.1,
5413         -1.0,    1.0,   0.1,
5414          0.0,    1.0,   0.1
5415     };
5416
5417     HRESULT hr;
5418     DWORD color;
5419     IDirect3DPixelShader9 *pixelshader = NULL;
5420     IDirect3DVertexShader9 *vs_1_shader = NULL;
5421     IDirect3DVertexShader9 *vs_2_shader = NULL;
5422     IDirect3DVertexShader9 *vs_3_shader = NULL;
5423
5424     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5425
5426     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5427     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5428     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5429     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5430     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5431     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5432     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5433     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5434     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5435     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5436     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5437
5438     hr = IDirect3DDevice9_BeginScene(device);
5439     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5440     if(SUCCEEDED(hr))
5441     {
5442         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5443         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5444         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5445         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5446
5447         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5448         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5450         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5451
5452         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5453         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5454         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5455         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5456
5457         hr = IDirect3DDevice9_EndScene(device);
5458         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5459     }
5460     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5461     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5462
5463     color = getPixelColor(device, 160, 120);
5464     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5465        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5466        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5467        "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5468     color = getPixelColor(device, 160, 360);
5469     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5470        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5471        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5472        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5473     color = getPixelColor(device, 480, 360);
5474     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5475        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5476        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5477        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5478
5479     /* cleanup */
5480     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5481     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5482     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5483     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5484     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5485     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5486     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5487     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5488 }
5489
5490 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5491     static const DWORD vs_code[] = {
5492     0xfffe0300,                                                             /* vs_3_0                       */
5493     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5494     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5495     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5496     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5497     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5498     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5499     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5500     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5501     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5502     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5503     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5504     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5505     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5506
5507     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5508     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5509     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5510     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5511     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5512     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5513     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5514     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5515     0x0000ffff                                                              /* end                          */
5516     };
5517     static const DWORD ps_1_code[] = {
5518     0xffff0104,                                                             /* ps_1_4                       */
5519     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5520     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5521     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5522     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5523     0x0000ffff                                                              /* end                          */
5524     };
5525     static const DWORD ps_2_code[] = {
5526     0xffff0200,                                                             /* ps_2_0                       */
5527     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5528     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5529     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5530
5531     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5532     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5533     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5534     0x0000ffff                                                              /* end                          */
5535     };
5536     static const DWORD ps_3_code[] = {
5537     0xffff0300,                                                             /* ps_3_0                       */
5538     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5539     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5540     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5541
5542     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5543     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5544     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5545     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5546     0x0000ffff                                                              /* end                          */
5547     };
5548
5549     float quad1[] =  {
5550         -1.0,   -1.0,   0.1,
5551          0.0,   -1.0,   0.1,
5552         -1.0,    0.0,   0.1,
5553          0.0,    0.0,   0.1
5554     };
5555     float quad2[] =  {
5556          0.0,   -1.0,   0.1,
5557          1.0,   -1.0,   0.1,
5558          0.0,    0.0,   0.1,
5559          1.0,    0.0,   0.1
5560     };
5561     float quad3[] =  {
5562         -1.0,    0.0,   0.1,
5563          0.0,    0.0,   0.1,
5564         -1.0,    1.0,   0.1,
5565          0.0,    1.0,   0.1
5566     };
5567     float quad4[] =  {
5568          0.0,    0.0,   0.1,
5569          1.0,    0.0,   0.1,
5570          0.0,    1.0,   0.1,
5571          1.0,    1.0,   0.1
5572     };
5573
5574     HRESULT hr;
5575     DWORD color;
5576     IDirect3DVertexShader9 *vertexshader = NULL;
5577     IDirect3DPixelShader9 *ps_1_shader = NULL;
5578     IDirect3DPixelShader9 *ps_2_shader = NULL;
5579     IDirect3DPixelShader9 *ps_3_shader = NULL;
5580     IDirect3DTexture9 *texture = NULL;
5581     D3DLOCKED_RECT lr;
5582     unsigned int x, y;
5583
5584     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5585
5586     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5587     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5588     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5589     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5590     for(y = 0; y < 512; y++) {
5591         for(x = 0; x < 512; x++) {
5592             double r_f = (double) x / (double) 512;
5593             double g_f = (double) y / (double) 512;
5594             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5595             unsigned short r = (unsigned short) (r_f * 65535.0);
5596             unsigned short g = (unsigned short) (g_f * 65535.0);
5597             dst[0] = r;
5598             dst[1] = g;
5599             dst[2] = 0;
5600             dst[3] = 65535;
5601         }
5602     }
5603     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5604     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5605
5606     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5607     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5608     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5609     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5610     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5611     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5612     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5613     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5614     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5615     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5616     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5617
5618     hr = IDirect3DDevice9_BeginScene(device);
5619     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5620     if(SUCCEEDED(hr))
5621     {
5622         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5623         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5624         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5625         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5626
5627         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5628         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5629         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5630         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5631
5632         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5633         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5635         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5636
5637         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5638         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5639         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5640         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5641         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5642         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5643         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5644         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5645         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5646         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5647
5648         hr = IDirect3DDevice9_EndScene(device);
5649         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5650     }
5651     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5652     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5653
5654     color = getPixelColor(device, 160, 120);
5655     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5656        (color & 0x0000ff00) == 0x0000ff00 &&
5657        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5658        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5659     color = getPixelColor(device, 160, 360);
5660     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5661        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5662        (color & 0x000000ff) == 0x00000000,
5663        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5664     color = getPixelColor(device, 480, 360);
5665     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5666        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5667        (color & 0x000000ff) == 0x00000000,
5668        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5669     color = getPixelColor(device, 480, 160);
5670     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5671        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5672        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5673        (color & 0x000000ff) == 0x00000000),
5674        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5675
5676     /* cleanup */
5677     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5678     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5679     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5680     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5681     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5682     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5683     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5684     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5685     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5686     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5687     if(texture) IDirect3DTexture9_Release(texture);
5688 }
5689
5690 void test_compare_instructions(IDirect3DDevice9 *device)
5691 {
5692     DWORD shader_sge_vec_code[] = {
5693         0xfffe0101,                                         /* vs_1_1                   */
5694         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5695         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5696         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5697         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5698         0x0000ffff                                          /* end                      */
5699     };
5700     DWORD shader_slt_vec_code[] = {
5701         0xfffe0101,                                         /* vs_1_1                   */
5702         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5703         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5704         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5705         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5706         0x0000ffff                                          /* end                      */
5707     };
5708     DWORD shader_sge_scalar_code[] = {
5709         0xfffe0101,                                         /* vs_1_1                   */
5710         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5711         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5712         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5713         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5714         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5715         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5716         0x0000ffff                                          /* end                      */
5717     };
5718     DWORD shader_slt_scalar_code[] = {
5719         0xfffe0101,                                         /* vs_1_1                   */
5720         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5721         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5722         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5723         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5724         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5725         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5726         0x0000ffff                                          /* end                      */
5727     };
5728     IDirect3DVertexShader9 *shader_sge_vec;
5729     IDirect3DVertexShader9 *shader_slt_vec;
5730     IDirect3DVertexShader9 *shader_sge_scalar;
5731     IDirect3DVertexShader9 *shader_slt_scalar;
5732     HRESULT hr, color;
5733     float quad1[] =  {
5734         -1.0,   -1.0,   0.1,
5735          0.0,   -1.0,   0.1,
5736         -1.0,    0.0,   0.1,
5737          0.0,    0.0,   0.1
5738     };
5739     float quad2[] =  {
5740          0.0,   -1.0,   0.1,
5741          1.0,   -1.0,   0.1,
5742          0.0,    0.0,   0.1,
5743          1.0,    0.0,   0.1
5744     };
5745     float quad3[] =  {
5746         -1.0,    0.0,   0.1,
5747          0.0,    0.0,   0.1,
5748         -1.0,    1.0,   0.1,
5749          0.0,    1.0,   0.1
5750     };
5751     float quad4[] =  {
5752          0.0,    0.0,   0.1,
5753          1.0,    0.0,   0.1,
5754          0.0,    1.0,   0.1,
5755          1.0,    1.0,   0.1
5756     };
5757     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5758     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5759
5760     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5761
5762     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5763     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5764     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5765     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5766     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5767     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5768     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5769     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5770     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5771     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5772     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5773     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5774     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5775     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5776
5777     hr = IDirect3DDevice9_BeginScene(device);
5778     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5779     if(SUCCEEDED(hr))
5780     {
5781         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5782         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5783         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5784         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5785
5786         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5787         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5788         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5789         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5790
5791         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5792         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5794         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5795
5796         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5797         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5798
5799         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5800         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5803
5804         hr = IDirect3DDevice9_EndScene(device);
5805         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5806     }
5807
5808     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5809     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5810
5811     color = getPixelColor(device, 160, 360);
5812     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5813     color = getPixelColor(device, 480, 360);
5814     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5815     color = getPixelColor(device, 160, 120);
5816     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5817     color = getPixelColor(device, 480, 160);
5818     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5819
5820     IDirect3DVertexShader9_Release(shader_sge_vec);
5821     IDirect3DVertexShader9_Release(shader_slt_vec);
5822     IDirect3DVertexShader9_Release(shader_sge_scalar);
5823     IDirect3DVertexShader9_Release(shader_slt_scalar);
5824 }
5825
5826 void test_vshader_input(IDirect3DDevice9 *device)
5827 {
5828     DWORD swapped_shader_code_3[] = {
5829         0xfffe0300,                                         /* vs_3_0               */
5830         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5831         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5832         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5833         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5834         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5835         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5836         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5837         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5838         0x0000ffff                                          /* end                  */
5839     };
5840     DWORD swapped_shader_code_1[] = {
5841         0xfffe0101,                                         /* vs_1_1               */
5842         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5843         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5844         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5845         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5846         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5847         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5848         0x0000ffff                                          /* end                  */
5849     };
5850     DWORD swapped_shader_code_2[] = {
5851         0xfffe0200,                                         /* vs_2_0               */
5852         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5853         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5854         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5855         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5856         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5857         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5858         0x0000ffff                                          /* end                  */
5859     };
5860     DWORD texcoord_color_shader_code_3[] = {
5861         0xfffe0300,                                         /* vs_3_0               */
5862         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5863         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5864         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5865         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5866         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5867         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5868         0x0000ffff                                          /* end                  */
5869     };
5870     DWORD texcoord_color_shader_code_2[] = {
5871         0xfffe0200,                                         /* vs_2_0               */
5872         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5873         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5874         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5875         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5876         0x0000ffff                                          /* end                  */
5877     };
5878     DWORD texcoord_color_shader_code_1[] = {
5879         0xfffe0101,                                         /* vs_1_1               */
5880         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5881         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5882         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5883         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5884         0x0000ffff                                          /* end                  */
5885     };
5886     DWORD color_color_shader_code_3[] = {
5887         0xfffe0300,                                         /* vs_3_0               */
5888         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5889         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5890         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5891         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5892         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5893         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5894         0x0000ffff                                          /* end                  */
5895     };
5896     DWORD color_color_shader_code_2[] = {
5897         0xfffe0200,                                         /* vs_2_0               */
5898         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5899         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5900         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5901         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5902         0x0000ffff                                          /* end                  */
5903     };
5904     DWORD color_color_shader_code_1[] = {
5905         0xfffe0101,                                         /* vs_1_1               */
5906         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5907         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5908         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5909         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5910         0x0000ffff                                          /* end                  */
5911     };
5912     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5913     HRESULT hr;
5914     DWORD color, r, g, b;
5915     float quad1[] =  {
5916         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5917          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5918         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5919          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5920     };
5921     float quad2[] =  {
5922          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5923          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5924          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5925          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5926     };
5927     float quad3[] =  {
5928         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5929          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5930         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5931          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5932     };
5933     float quad4[] =  {
5934          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5935          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5936          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5937          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5938     };
5939     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5940         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5941         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5942         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5943         D3DDECL_END()
5944     };
5945     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5946         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5947         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5948         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5949         D3DDECL_END()
5950     };
5951     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5952         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5953         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5954         D3DDECL_END()
5955     };
5956     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5957         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5958         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5959         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5960         D3DDECL_END()
5961     };
5962     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5963         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5964         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5965         D3DDECL_END()
5966     };
5967     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5968         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5969         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5970         D3DDECL_END()
5971     };
5972     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5973         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5974         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5975         D3DDECL_END()
5976     };
5977     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5978         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5979         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5980         D3DDECL_END()
5981     };
5982     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5983     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5984     unsigned int i;
5985     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5986     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5987
5988     struct vertex quad1_color[] =  {
5989        {-1.0,   -1.0,   0.1,    0x00ff8040},
5990        { 0.0,   -1.0,   0.1,    0x00ff8040},
5991        {-1.0,    0.0,   0.1,    0x00ff8040},
5992        { 0.0,    0.0,   0.1,    0x00ff8040}
5993     };
5994     struct vertex quad2_color[] =  {
5995        { 0.0,   -1.0,   0.1,    0x00ff8040},
5996        { 1.0,   -1.0,   0.1,    0x00ff8040},
5997        { 0.0,    0.0,   0.1,    0x00ff8040},
5998        { 1.0,    0.0,   0.1,    0x00ff8040}
5999     };
6000     struct vertex quad3_color[] =  {
6001        {-1.0,    0.0,   0.1,    0x00ff8040},
6002        { 0.0,    0.0,   0.1,    0x00ff8040},
6003        {-1.0,    1.0,   0.1,    0x00ff8040},
6004        { 0.0,    1.0,   0.1,    0x00ff8040}
6005     };
6006     float quad4_color[] =  {
6007          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6008          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6009          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6010          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6011     };
6012
6013     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6014     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6015     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6016     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6017     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6018     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6019     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6020     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6021
6022     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6023     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6024     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6025     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6026     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6027     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6028     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6029     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6030
6031     for(i = 1; i <= 3; i++) {
6032         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6033         if(i == 3) {
6034             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6035             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6036         } else if(i == 2){
6037             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6038             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6039         } else if(i == 1) {
6040             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6041             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6042         }
6043
6044         hr = IDirect3DDevice9_BeginScene(device);
6045         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6046         if(SUCCEEDED(hr))
6047         {
6048             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6049             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6050
6051             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6052             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6053             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6054             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6055
6056             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6057             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6058             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6059             if(i == 3 || i == 2) {
6060                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6061             } else if(i == 1) {
6062                 /* Succeeds or fails, depending on SW or HW vertex processing */
6063                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6064             }
6065
6066             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6067             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6068             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6069             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6070
6071             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6072             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6073             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6074             if(i == 3 || i == 2) {
6075                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6076             } else if(i == 1) {
6077                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6078             }
6079
6080             hr = IDirect3DDevice9_EndScene(device);
6081             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6082         }
6083
6084         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6085         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6086
6087         if(i == 3 || i == 2) {
6088             color = getPixelColor(device, 160, 360);
6089             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6090                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6091
6092             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6093             color = getPixelColor(device, 480, 360);
6094             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6095                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6096             color = getPixelColor(device, 160, 120);
6097             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6098             ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
6099                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6100
6101             color = getPixelColor(device, 480, 160);
6102             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6103         } else if(i == 1) {
6104             color = getPixelColor(device, 160, 360);
6105             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6106                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6107             color = getPixelColor(device, 480, 360);
6108             /* Accept the clear color as well in this case, since SW VP returns an error */
6109             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6110             color = getPixelColor(device, 160, 120);
6111             ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6112                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6113             color = getPixelColor(device, 480, 160);
6114             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6115         }
6116
6117         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6118         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6119
6120         /* Now find out if the whole streams are re-read, or just the last active value for the
6121          * vertices is used.
6122          */
6123         hr = IDirect3DDevice9_BeginScene(device);
6124         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6125         if(SUCCEEDED(hr))
6126         {
6127             float quad1_modified[] =  {
6128                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6129                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6130                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6131                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6132             };
6133             float quad2_modified[] =  {
6134                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6135                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6136                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6137                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6138             };
6139
6140             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6141             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6142
6143             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6144             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6145             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6146             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6147
6148             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6149             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6150             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6151             if(i == 3 || i == 2) {
6152                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6153             } else if(i == 1) {
6154                 /* Succeeds or fails, depending on SW or HW vertex processing */
6155                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6156             }
6157
6158             hr = IDirect3DDevice9_EndScene(device);
6159             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6160         }
6161         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6162         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6163
6164         color = getPixelColor(device, 480, 350);
6165         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6166          * as well.
6167          *
6168          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6169          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6170          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6171          * refrast's result.
6172          *
6173          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6174          */
6175         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6176            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6177         color = getPixelColor(device, 160, 120);
6178
6179         IDirect3DDevice9_SetVertexShader(device, NULL);
6180         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6181
6182         IDirect3DVertexShader9_Release(swapped_shader);
6183     }
6184
6185     for(i = 1; i <= 3; i++) {
6186         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6187         if(i == 3) {
6188             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6189             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6190             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6191             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6192         } else if(i == 2){
6193             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6194             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6195             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6196             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6197         } else if(i == 1) {
6198             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6199             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6200             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6201             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6202         }
6203
6204         hr = IDirect3DDevice9_BeginScene(device);
6205         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6206         if(SUCCEEDED(hr))
6207         {
6208             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6209             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6210             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6212             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6213             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6214
6215             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6216             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6217
6218             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6219             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6220             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6221             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6222             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6223             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6224
6225             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6226             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6227             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6228             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6229             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6230             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6231
6232             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6233             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6234             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6235             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6236
6237             hr = IDirect3DDevice9_EndScene(device);
6238             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6239         }
6240         IDirect3DDevice9_SetVertexShader(device, NULL);
6241         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6242
6243         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6244         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6245
6246         color = getPixelColor(device, 160, 360);
6247         r = (color & 0x00ff0000) >> 16;
6248         g = (color & 0x0000ff00) >>  8;
6249         b = (color & 0x000000ff) >>  0;
6250         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6251            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6252         color = getPixelColor(device, 480, 360);
6253         r = (color & 0x00ff0000) >> 16;
6254         g = (color & 0x0000ff00) >>  8;
6255         b = (color & 0x000000ff) >>  0;
6256         ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6257            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6258         color = getPixelColor(device, 160, 120);
6259         r = (color & 0x00ff0000) >> 16;
6260         g = (color & 0x0000ff00) >>  8;
6261         b = (color & 0x000000ff) >>  0;
6262         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6263            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6264         color = getPixelColor(device, 480, 160);
6265         r = (color & 0x00ff0000) >> 16;
6266         g = (color & 0x0000ff00) >>  8;
6267         b = (color & 0x000000ff) >>  0;
6268         ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6269            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6270
6271         IDirect3DVertexShader9_Release(texcoord_color_shader);
6272         IDirect3DVertexShader9_Release(color_color_shader);
6273     }
6274
6275     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6276     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6277     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6278     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6279
6280     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6281     IDirect3DVertexDeclaration9_Release(decl_color_color);
6282     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6283     IDirect3DVertexDeclaration9_Release(decl_color_float);
6284 }
6285
6286 static void srgbtexture_test(IDirect3DDevice9 *device)
6287 {
6288     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6289      * texture stage state to render a quad using that texture.  The resulting
6290      * color components should be 0x36 (~ 0.21), per this formula:
6291      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6292      * This is true where srgb_color > 0.04045.
6293      */
6294     IDirect3D9 *d3d = NULL;
6295     HRESULT hr;
6296     LPDIRECT3DTEXTURE9 texture = NULL;
6297     LPDIRECT3DSURFACE9 surface = NULL;
6298     D3DLOCKED_RECT lr;
6299     DWORD color;
6300     float quad[] = {
6301         -1.0,       1.0,       0.0,     0.0,    0.0,
6302          1.0,       1.0,       0.0,     1.0,    0.0,
6303         -1.0,      -1.0,       0.0,     0.0,    1.0,
6304          1.0,      -1.0,       0.0,     1.0,    1.0,
6305     };
6306
6307
6308     memset(&lr, 0, sizeof(lr));
6309     IDirect3DDevice9_GetDirect3D(device, &d3d);
6310     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6311                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6312                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6313         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6314         goto out;
6315     }
6316
6317     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6318                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6319                                         &texture, NULL);
6320     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6321     if(!texture) {
6322         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6323         goto out;
6324     }
6325     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6326     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6327
6328     fill_surface(surface, 0xff7f7f7f);
6329     IDirect3DSurface9_Release(surface);
6330
6331     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6332     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6333     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6334     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6335
6336     hr = IDirect3DDevice9_BeginScene(device);
6337     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6338     if(SUCCEEDED(hr))
6339     {
6340         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6341         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6342
6343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6345
6346
6347         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6348         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6349
6350         hr = IDirect3DDevice9_EndScene(device);
6351         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6352     }
6353
6354     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6355     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6356     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6357     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6358
6359     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6360     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6361
6362     color = getPixelColor(device, 320, 240);
6363     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6364
6365 out:
6366     if(texture) IDirect3DTexture9_Release(texture);
6367     IDirect3D9_Release(d3d);
6368 }
6369
6370 /* Return true if color is near the expected value */
6371 static int color_near(DWORD color, DWORD expected)
6372 {
6373     const BYTE slop = 1;
6374
6375     BYTE r, g, b;
6376     BYTE rx, gx, bx;
6377     r = (color & 0x00ff0000) >> 16;
6378     g = (color & 0x0000ff00) >>  8;
6379     b = (color & 0x000000ff);
6380     rx = (expected & 0x00ff0000) >> 16;
6381     gx = (expected & 0x0000ff00) >>  8;
6382     bx = (expected & 0x000000ff);
6383
6384     return
6385       ((r >= (rx - slop)) && (r <= (rx + slop))) &&
6386       ((g >= (gx - slop)) && (g <= (gx + slop))) &&
6387       ((b >= (bx - slop)) && (b <= (bx + slop)));
6388 }
6389
6390 static void shademode_test(IDirect3DDevice9 *device)
6391 {
6392     /* Render a quad and try all of the different fixed function shading models. */
6393     HRESULT hr;
6394     DWORD color0, color1;
6395     DWORD color0_gouraud = 0, color1_gouraud = 0;
6396     DWORD shademode = D3DSHADE_FLAT;
6397     DWORD primtype = D3DPT_TRIANGLESTRIP;
6398     LPVOID data = NULL;
6399     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6400     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6401     UINT i, j;
6402     struct vertex quad_strip[] =
6403     {
6404         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6405         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6406         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6407         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6408     };
6409     struct vertex quad_list[] =
6410     {
6411         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6412         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6413         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6414
6415         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6416         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6417         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6418     };
6419
6420     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6421                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6422     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6423     if (FAILED(hr)) goto bail;
6424
6425     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6426                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6427     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6428     if (FAILED(hr)) goto bail;
6429
6430     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6431     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6432
6433     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6434     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6435
6436     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6437     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6438     memcpy(data, quad_strip, sizeof(quad_strip));
6439     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6440     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6441
6442     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6443     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6444     memcpy(data, quad_list, sizeof(quad_list));
6445     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6446     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6447
6448     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6449      * the color fixups we have to do for FLAT shading will be dependent on that. */
6450     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6451     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6452
6453     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6454     for (j=0; j<2; j++) {
6455
6456         /* Inner loop just changes the D3DRS_SHADEMODE */
6457         for (i=0; i<3; i++) {
6458             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6459             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6460
6461             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6462             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6463
6464             hr = IDirect3DDevice9_BeginScene(device);
6465             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6466             if(SUCCEEDED(hr))
6467             {
6468                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6469                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6470
6471                 hr = IDirect3DDevice9_EndScene(device);
6472                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6473             }
6474
6475             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6476             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6477
6478             /* Sample two spots from the output */
6479             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6480             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6481             switch(shademode) {
6482                 case D3DSHADE_FLAT:
6483                     /* Should take the color of the first vertex of each triangle */
6484                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6485                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6486                     shademode = D3DSHADE_GOURAUD;
6487                     break;
6488                 case D3DSHADE_GOURAUD:
6489                     /* Should be an interpolated blend */
6490
6491                     ok(color_near(color0, 0x000dca28),
6492                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6493                     ok(color_near(color1, 0x000d45c7),
6494                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6495
6496                     color0_gouraud = color0;
6497                     color1_gouraud = color1;
6498
6499                     shademode = D3DSHADE_PHONG;
6500                     break;
6501                 case D3DSHADE_PHONG:
6502                     /* Should be the same as GOURAUD, since no hardware implements this */
6503                     ok(color_near(color0, 0x000dca28),
6504                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6505                     ok(color_near(color1, 0x000d45c7),
6506                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6507
6508                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6509                             color0_gouraud, color0);
6510                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6511                             color1_gouraud, color1);
6512                     break;
6513             }
6514         }
6515         /* Now, do it all over again with a TRIANGLELIST */
6516         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6517         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6518         primtype = D3DPT_TRIANGLELIST;
6519         shademode = D3DSHADE_FLAT;
6520     }
6521
6522 bail:
6523     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6524     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6525     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6526     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6527
6528     if (vb_strip)
6529         IDirect3DVertexBuffer9_Release(vb_strip);
6530     if (vb_list)
6531         IDirect3DVertexBuffer9_Release(vb_list);
6532 }
6533
6534
6535 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6536 {
6537     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6538      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6539      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6540      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6541      * 0.73
6542      *
6543      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6544      * so use shaders for this task
6545      */
6546     IDirect3DPixelShader9 *pshader;
6547     IDirect3DVertexShader9 *vshader;
6548     IDirect3D9 *d3d;
6549     DWORD vshader_code[] = {
6550         0xfffe0101,                                                             /* vs_1_1                       */
6551         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6552         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6553         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6554         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6555         0x0000ffff                                                              /* end                          */
6556     };
6557     DWORD pshader_code[] = {
6558         0xffff0101,                                                             /* ps_1_1                       */
6559         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6560         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6561         0x0000ffff                                                              /* end                          */
6562     };
6563     const float quad[] = {
6564        -1.0,   -1.0,    0.1,
6565         1.0,   -1.0,    0.1,
6566        -1.0,    1.0,    0.1,
6567         1.0,    1.0,    0.1
6568     };
6569     HRESULT hr;
6570     DWORD color;
6571
6572     IDirect3DDevice9_GetDirect3D(device, &d3d);
6573     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6574      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6575      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6576      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6577      * works
6578      */
6579     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6580                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6581                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6582         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6583         IDirect3D9_Release(d3d);
6584         return;
6585     }
6586     IDirect3D9_Release(d3d);
6587
6588     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6589     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6590
6591     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6592     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6593     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6594     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6595     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6596     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6597     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6598     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6599     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6600     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6601
6602     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6603     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6604     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6605     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6606     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6607     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6608     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6609     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6610     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6611     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6612
6613     hr = IDirect3DDevice9_BeginScene(device);
6614     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6615     if(SUCCEEDED(hr)) {
6616         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6617         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6618
6619         hr = IDirect3DDevice9_EndScene(device);
6620         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6621     }
6622
6623     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6624     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6625     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6626     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6627     IDirect3DPixelShader9_Release(pshader);
6628     IDirect3DVertexShader9_Release(vshader);
6629
6630     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6631     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6633     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6634
6635     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6636     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6637     color = getPixelColor(device, 160, 360);
6638     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6639        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6640 }
6641
6642 static void alpha_test(IDirect3DDevice9 *device)
6643 {
6644     HRESULT hr;
6645     IDirect3DTexture9 *offscreenTexture;
6646     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6647     DWORD color, red, green, blue;
6648
6649     struct vertex quad1[] =
6650     {
6651         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6652         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6653         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6654         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6655     };
6656     struct vertex quad2[] =
6657     {
6658         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6659         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6660         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6661         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6662     };
6663     static const float composite_quad[][5] = {
6664         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6665         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6666         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6667         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6668     };
6669
6670     /* Clear the render target with alpha = 0.5 */
6671     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6672     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6673
6674     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6675     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6676
6677     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6678     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6679     if(!backbuffer) {
6680         goto out;
6681     }
6682
6683     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6684     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6685     if(!offscreen) {
6686         goto out;
6687     }
6688
6689     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6690     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6691
6692     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6693     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6694     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6695     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6696     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6697     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6698     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6699     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6701     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6702
6703     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6704     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6705     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6706
6707         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
6708          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
6709          * the input alpha
6710          *
6711          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
6712          * They give essentially ZERO and ONE blend factors
6713          */
6714         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6715         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6716         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6717         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6719         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6720
6721         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6722         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6723         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6724         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6725         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6726         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6727
6728         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
6729          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
6730          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
6731          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
6732          * vertices
6733          */
6734         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6735         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6736         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6737         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6738
6739         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6740         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6741         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6742         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6744         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6745
6746         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6747         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6748         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6749         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6750         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6751         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6752
6753         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6754         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6755
6756         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6757          * Disable alpha blending for the final composition
6758          */
6759         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6760         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6761         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6762         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6763
6764         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6765         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6767         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6768         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6769         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6770
6771         hr = IDirect3DDevice9_EndScene(device);
6772         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6773     }
6774
6775     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6776
6777     color = getPixelColor(device, 160, 360);
6778     red =   (color & 0x00ff0000) >> 16;
6779     green = (color & 0x0000ff00) >>  8;
6780     blue =  (color & 0x000000ff);
6781     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6782        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6783
6784     color = getPixelColor(device, 160, 120);
6785     red =   (color & 0x00ff0000) >> 16;
6786     green = (color & 0x0000ff00) >>  8;
6787     blue =  (color & 0x000000ff);
6788     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6789        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6790
6791     color = getPixelColor(device, 480, 360);
6792     red =   (color & 0x00ff0000) >> 16;
6793     green = (color & 0x0000ff00) >>  8;
6794     blue =  (color & 0x000000ff);
6795     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6796        "SRCALPHA on texture returned color %08x, expected bar\n", color);
6797
6798     color = getPixelColor(device, 480, 120);
6799     red =   (color & 0x00ff0000) >> 16;
6800     green = (color & 0x0000ff00) >>  8;
6801     blue =  (color & 0x000000ff);
6802     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6803        "DSTALPHA on texture returned color %08x, expected 0x00800080\n", color);
6804
6805     out:
6806     /* restore things */
6807     if(backbuffer) {
6808         IDirect3DSurface9_Release(backbuffer);
6809     }
6810     if(offscreenTexture) {
6811         IDirect3DTexture9_Release(offscreenTexture);
6812     }
6813     if(offscreen) {
6814         IDirect3DSurface9_Release(offscreen);
6815     }
6816 }
6817
6818 struct vertex_shortcolor {
6819     float x, y, z;
6820     unsigned short r, g, b, a;
6821 };
6822 struct vertex_floatcolor {
6823     float x, y, z;
6824     float r, g, b, a;
6825 };
6826
6827 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6828 {
6829     HRESULT hr;
6830     BOOL s_ok, ub_ok, f_ok;
6831     DWORD color, size, i;
6832     void *data;
6833     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6834         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6835         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6836         D3DDECL_END()
6837     };
6838     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6839         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6840         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6841         D3DDECL_END()
6842     };
6843     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6844         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6845         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6846         D3DDECL_END()
6847     };
6848     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6849         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6850         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6851         D3DDECL_END()
6852     };
6853     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6854         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6855         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6856         D3DDECL_END()
6857     };
6858     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6859         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6860         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6861         D3DDECL_END()
6862     };
6863     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6864         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6865         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6866         D3DDECL_END()
6867     };
6868     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6869     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6870     IDirect3DVertexBuffer9 *vb, *vb2;
6871     struct vertex quad1[] =                             /* D3DCOLOR */
6872     {
6873         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6874         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6875         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6876         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6877     };
6878     struct vertex quad2[] =                             /* UBYTE4N */
6879     {
6880         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6881         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6882         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6883         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6884     };
6885     struct vertex_shortcolor quad3[] =                  /* short */
6886     {
6887         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6888         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6889         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6890         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6891     };
6892     struct vertex_floatcolor quad4[] =
6893     {
6894         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6895         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6896         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6897         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6898     };
6899     DWORD colors[] = {
6900         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6901         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6902         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6903         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6904         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6905         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6906         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6907         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6908         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6909         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6910         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6911         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6912         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6913         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6914         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6915         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6916     };
6917     float quads[] = {
6918         -1.0,   -1.0,     0.1,
6919         -1.0,    0.0,     0.1,
6920          0.0,   -1.0,     0.1,
6921          0.0,    0.0,     0.1,
6922
6923          0.0,   -1.0,     0.1,
6924          0.0,    0.0,     0.1,
6925          1.0,   -1.0,     0.1,
6926          1.0,    0.0,     0.1,
6927
6928          0.0,    0.0,     0.1,
6929          0.0,    1.0,     0.1,
6930          1.0,    0.0,     0.1,
6931          1.0,    1.0,     0.1,
6932
6933         -1.0,    0.0,     0.1,
6934         -1.0,    1.0,     0.1,
6935          0.0,    0.0,     0.1,
6936          0.0,    1.0,     0.1
6937     };
6938     struct tvertex quad_transformed[] = {
6939        {  90,    110,     0.1,      2.0,        0x00ffff00},
6940        { 570,    110,     0.1,      2.0,        0x00ffff00},
6941        {  90,    300,     0.1,      2.0,        0x00ffff00},
6942        { 570,    300,     0.1,      2.0,        0x00ffff00}
6943     };
6944     D3DCAPS9 caps;
6945
6946     memset(&caps, 0, sizeof(caps));
6947     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6948     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6949
6950     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6951     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6952
6953     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6954     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6955     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6956     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6957     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6958     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6959     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6960         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6961         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6962         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6963         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6964     } else {
6965         trace("D3DDTCAPS_UBYTE4N not supported\n");
6966         dcl_ubyte_2 = NULL;
6967         dcl_ubyte = NULL;
6968     }
6969     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6970     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6971     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6972     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6973
6974     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6975     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6976                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6977     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6978
6979     hr = IDirect3DDevice9_BeginScene(device);
6980     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6981     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6982     if(SUCCEEDED(hr)) {
6983         if(dcl_color) {
6984             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6985             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6986             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6987             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6988         }
6989
6990         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6991          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6992          * using software vertex processing. Doh!
6993          */
6994         if(dcl_ubyte) {
6995             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6996             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6997             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6998             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6999             ub_ok = SUCCEEDED(hr);
7000         }
7001
7002         if(dcl_short) {
7003             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7004             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7005             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7006             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7007             s_ok = SUCCEEDED(hr);
7008         }
7009
7010         if(dcl_float) {
7011             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7012             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7013             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7014             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7015             f_ok = SUCCEEDED(hr);
7016         }
7017
7018         hr = IDirect3DDevice9_EndScene(device);
7019         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7020     }
7021
7022     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7023     if(dcl_short) {
7024         color = getPixelColor(device, 480, 360);
7025         ok(color == 0x000000ff || !s_ok,
7026            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7027     }
7028     if(dcl_ubyte) {
7029         color = getPixelColor(device, 160, 120);
7030         ok(color == 0x0000ffff || !ub_ok,
7031            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7032     }
7033     if(dcl_color) {
7034         color = getPixelColor(device, 160, 360);
7035         ok(color == 0x00ffff00,
7036            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7037     }
7038     if(dcl_float) {
7039         color = getPixelColor(device, 480, 120);
7040         ok(color == 0x00ff0000 || !f_ok,
7041            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7042     }
7043
7044     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7045      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7046      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7047      * whether the immediate mode code works
7048      */
7049     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7050     hr = IDirect3DDevice9_BeginScene(device);
7051     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7052     if(SUCCEEDED(hr)) {
7053         if(dcl_color) {
7054             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7055             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7056             memcpy(data, quad1, sizeof(quad1));
7057             hr = IDirect3DVertexBuffer9_Unlock(vb);
7058             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7059             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7060             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7061             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7062             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7063             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7064             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7065         }
7066
7067         if(dcl_ubyte) {
7068             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7069             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7070             memcpy(data, quad2, sizeof(quad2));
7071             hr = IDirect3DVertexBuffer9_Unlock(vb);
7072             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7073             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7074             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7075             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7076             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7077             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7078             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7079                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7080             ub_ok = SUCCEEDED(hr);
7081         }
7082
7083         if(dcl_short) {
7084             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7085             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7086             memcpy(data, quad3, sizeof(quad3));
7087             hr = IDirect3DVertexBuffer9_Unlock(vb);
7088             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7089             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7090             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7091             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7092             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7093             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7094             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7095                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7096             s_ok = SUCCEEDED(hr);
7097         }
7098
7099         if(dcl_float) {
7100             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7101             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7102             memcpy(data, quad4, sizeof(quad4));
7103             hr = IDirect3DVertexBuffer9_Unlock(vb);
7104             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7105             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7106             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7107             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7108             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7109             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7110             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7111                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7112             f_ok = SUCCEEDED(hr);
7113         }
7114
7115         hr = IDirect3DDevice9_EndScene(device);
7116         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7117     }
7118
7119     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7120     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7121     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7122     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7123
7124     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7125     if(dcl_short) {
7126         color = getPixelColor(device, 480, 360);
7127         ok(color == 0x000000ff || !s_ok,
7128            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7129     }
7130     if(dcl_ubyte) {
7131         color = getPixelColor(device, 160, 120);
7132         ok(color == 0x0000ffff || !ub_ok,
7133            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7134     }
7135     if(dcl_color) {
7136         color = getPixelColor(device, 160, 360);
7137         ok(color == 0x00ffff00,
7138            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7139     }
7140     if(dcl_float) {
7141         color = getPixelColor(device, 480, 120);
7142         ok(color == 0x00ff0000 || !f_ok,
7143            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7144     }
7145
7146     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7147     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7148
7149     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7150     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7151     memcpy(data, quad_transformed, sizeof(quad_transformed));
7152     hr = IDirect3DVertexBuffer9_Unlock(vb);
7153     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7154
7155     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7156     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7157
7158     hr = IDirect3DDevice9_BeginScene(device);
7159     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7160     if(SUCCEEDED(hr)) {
7161         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7162         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7163         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7164         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7165
7166         hr = IDirect3DDevice9_EndScene(device);
7167         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7168     }
7169
7170     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7171     color = getPixelColor(device, 88, 108);
7172     ok(color == 0x000000ff,
7173        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7174     color = getPixelColor(device, 92, 108);
7175     ok(color == 0x000000ff,
7176        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7177     color = getPixelColor(device, 88, 112);
7178     ok(color == 0x000000ff,
7179        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7180     color = getPixelColor(device, 92, 112);
7181     ok(color == 0x00ffff00,
7182        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7183
7184     color = getPixelColor(device, 568, 108);
7185     ok(color == 0x000000ff,
7186        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7187     color = getPixelColor(device, 572, 108);
7188     ok(color == 0x000000ff,
7189        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7190     color = getPixelColor(device, 568, 112);
7191     ok(color == 0x00ffff00,
7192        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7193     color = getPixelColor(device, 572, 112);
7194     ok(color == 0x000000ff,
7195        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7196
7197     color = getPixelColor(device, 88, 298);
7198     ok(color == 0x000000ff,
7199        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7200     color = getPixelColor(device, 92, 298);
7201     ok(color == 0x00ffff00,
7202        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7203     color = getPixelColor(device, 88, 302);
7204     ok(color == 0x000000ff,
7205        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7206     color = getPixelColor(device, 92, 302);
7207     ok(color == 0x000000ff,
7208        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7209
7210     color = getPixelColor(device, 568, 298);
7211     ok(color == 0x00ffff00,
7212        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7213     color = getPixelColor(device, 572, 298);
7214     ok(color == 0x000000ff,
7215        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7216     color = getPixelColor(device, 568, 302);
7217     ok(color == 0x000000ff,
7218        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7219     color = getPixelColor(device, 572, 302);
7220     ok(color == 0x000000ff,
7221        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7222
7223     /* This test is pointless without those two declarations: */
7224     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7225         skip("color-ubyte switching test declarations aren't supported\n");
7226         goto out;
7227     }
7228
7229     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7230     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7231     memcpy(data, quads, sizeof(quads));
7232     hr = IDirect3DVertexBuffer9_Unlock(vb);
7233     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7234     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7235                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7236     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7237     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7238     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7239     memcpy(data, colors, sizeof(colors));
7240     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7241     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7242
7243     for(i = 0; i < 2; i++) {
7244         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7245         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7246
7247         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7248         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7249         if(i == 0) {
7250             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7251         } else {
7252             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7253         }
7254         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7255
7256         hr = IDirect3DDevice9_BeginScene(device);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7258         ub_ok = FALSE;
7259         if(SUCCEEDED(hr)) {
7260             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7261             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7262             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7263             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7264                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7265             ub_ok = SUCCEEDED(hr);
7266
7267             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7268             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7269             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7270             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7271
7272             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7273             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7274             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7275             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7276                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7277             ub_ok = (SUCCEEDED(hr) && ub_ok);
7278
7279             hr = IDirect3DDevice9_EndScene(device);
7280             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7281         }
7282
7283         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7284         if(i == 0) {
7285             color = getPixelColor(device, 480, 360);
7286             ok(color == 0x00ff0000,
7287                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7288             color = getPixelColor(device, 160, 120);
7289             ok(color == 0x00ffffff,
7290                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7291             color = getPixelColor(device, 160, 360);
7292             ok(color == 0x000000ff || !ub_ok,
7293                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7294             color = getPixelColor(device, 480, 120);
7295             ok(color == 0x000000ff || !ub_ok,
7296                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7297         } else {
7298             color = getPixelColor(device, 480, 360);
7299             ok(color == 0x000000ff,
7300                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7301             color = getPixelColor(device, 160, 120);
7302             ok(color == 0x00ffffff,
7303                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7304             color = getPixelColor(device, 160, 360);
7305             ok(color == 0x00ff0000 || !ub_ok,
7306                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7307             color = getPixelColor(device, 480, 120);
7308             ok(color == 0x00ff0000 || !ub_ok,
7309                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7310         }
7311     }
7312
7313     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7314     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7315     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7316     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7317     IDirect3DVertexBuffer9_Release(vb2);
7318
7319     out:
7320     IDirect3DVertexBuffer9_Release(vb);
7321     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7322     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7323     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7324     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7325     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7326     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7327     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7328 }
7329
7330 struct vertex_float16color {
7331     float x, y, z;
7332     DWORD c1, c2;
7333 };
7334
7335 static void test_vshader_float16(IDirect3DDevice9 *device)
7336 {
7337     HRESULT hr;
7338     DWORD color;
7339     void *data;
7340     static const D3DVERTEXELEMENT9 decl_elements[] = {
7341         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7342         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7343         D3DDECL_END()
7344     };
7345     IDirect3DVertexDeclaration9 *vdecl = NULL;
7346     IDirect3DVertexBuffer9 *buffer = NULL;
7347     IDirect3DVertexShader9 *shader;
7348     DWORD shader_code[] = {
7349         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7350         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7351         0x90e40001, 0x0000ffff
7352     };
7353     struct vertex_float16color quad[] = {
7354         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7355         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7356         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7357         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7358
7359         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7360         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7361         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7362         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7363
7364         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7365         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7366         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7367         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7368
7369         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7370         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7371         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7372         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7373     };
7374
7375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7377
7378     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7379     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7380     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7381     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7382     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7383     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7384
7385     hr = IDirect3DDevice9_BeginScene(device);
7386     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7387     if(SUCCEEDED(hr)) {
7388         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7389         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7390         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7391         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7392         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7393         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7395         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7396         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7397         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7398
7399         hr = IDirect3DDevice9_EndScene(device);
7400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7401     }
7402     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7403     color = getPixelColor(device, 480, 360);
7404     ok(color == 0x00ff0000,
7405        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7406     color = getPixelColor(device, 160, 120);
7407     ok(color == 0x00000000,
7408        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7409     color = getPixelColor(device, 160, 360);
7410     ok(color == 0x0000ff00,
7411        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7412     color = getPixelColor(device, 480, 120);
7413     ok(color == 0x000000ff,
7414        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7415
7416     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7417     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7418
7419     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7420                                              D3DPOOL_MANAGED, &buffer, NULL);
7421     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7422     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7423     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7424     memcpy(data, quad, sizeof(quad));
7425     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7426     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7427     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7428     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7429
7430     hr = IDirect3DDevice9_BeginScene(device);
7431     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7432     if(SUCCEEDED(hr)) {
7433             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7434             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7435             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7436             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7437             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7438             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7439             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7440             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7441
7442             hr = IDirect3DDevice9_EndScene(device);
7443             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7444     }
7445
7446     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7447     color = getPixelColor(device, 480, 360);
7448     ok(color == 0x00ff0000,
7449        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7450     color = getPixelColor(device, 160, 120);
7451     ok(color == 0x00000000,
7452        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7453     color = getPixelColor(device, 160, 360);
7454     ok(color == 0x0000ff00,
7455        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7456     color = getPixelColor(device, 480, 120);
7457     ok(color == 0x000000ff,
7458        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7459
7460     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7461     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7462     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7463     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7464     IDirect3DDevice9_SetVertexShader(device, NULL);
7465     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7466
7467     IDirect3DVertexDeclaration9_Release(vdecl);
7468     IDirect3DVertexShader9_Release(shader);
7469     IDirect3DVertexBuffer9_Release(buffer);
7470 }
7471
7472 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7473 {
7474     D3DCAPS9 caps;
7475     IDirect3DTexture9 *texture;
7476     HRESULT hr;
7477     D3DLOCKED_RECT rect;
7478     unsigned int x, y;
7479     DWORD *dst, color;
7480     const float quad[] = {
7481         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7482          1.0,   -1.0,   0.1,    1.2,   -0.2,
7483         -1.0,    1.0,   0.1,   -0.2,    1.2,
7484          1.0,    1.0,   0.1,    1.2,    1.2
7485     };
7486     memset(&caps, 0, sizeof(caps));
7487
7488     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7489     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7490     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7491         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7492         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7493            "Card has conditional NP2 support without power of two restriction set\n");
7494         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7495         return;
7496     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7497         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7498         return;
7499     }
7500
7501     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7502     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7503
7504     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7506
7507     memset(&rect, 0, sizeof(rect));
7508     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7509     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7510     for(y = 0; y < 10; y++) {
7511         for(x = 0; x < 10; x++) {
7512             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7513             if(x == 0 || x == 9 || y == 0 || y == 9) {
7514                 *dst = 0x00ff0000;
7515             } else {
7516                 *dst = 0x000000ff;
7517             }
7518         }
7519     }
7520     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7521     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7522
7523     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7524     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7525     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7526     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7527     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7528     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7529     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7530     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7531
7532     hr = IDirect3DDevice9_BeginScene(device);
7533     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7534     if(SUCCEEDED(hr)) {
7535         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7536         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7537
7538         hr = IDirect3DDevice9_EndScene(device);
7539         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7540     }
7541
7542     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7543
7544     color = getPixelColor(device,    1,  1);
7545     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7546     color = getPixelColor(device, 639, 479);
7547     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7548
7549     color = getPixelColor(device, 135, 101);
7550     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7551     color = getPixelColor(device, 140, 101);
7552     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7553     color = getPixelColor(device, 135, 105);
7554     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7555     color = getPixelColor(device, 140, 105);
7556     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7557
7558     color = getPixelColor(device, 135, 376);
7559     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7560     color = getPixelColor(device, 140, 376);
7561     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7562     color = getPixelColor(device, 135, 379);
7563     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7564     color = getPixelColor(device, 140, 379);
7565     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7566
7567     color = getPixelColor(device, 500, 101);
7568     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7569     color = getPixelColor(device, 504, 101);
7570     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7571     color = getPixelColor(device, 500, 105);
7572     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7573     color = getPixelColor(device, 504, 105);
7574     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7575
7576     color = getPixelColor(device, 500, 376);
7577     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7578     color = getPixelColor(device, 504, 376);
7579     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7580     color = getPixelColor(device, 500, 380);
7581     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7582     color = getPixelColor(device, 504, 380);
7583     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7584
7585     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7586     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7587     IDirect3DTexture9_Release(texture);
7588 }
7589
7590 static void vFace_register_test(IDirect3DDevice9 *device)
7591 {
7592     HRESULT hr;
7593     DWORD color;
7594     const DWORD shader_code[] = {
7595         0xffff0300,                                                             /* ps_3_0                     */
7596         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7597         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7598         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7599         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7600         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7601         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7602         0x0000ffff                                                              /* END                        */
7603     };
7604     IDirect3DPixelShader9 *shader;
7605     IDirect3DTexture9 *texture;
7606     IDirect3DSurface9 *surface, *backbuffer;
7607     const float quad[] = {
7608         -1.0,   -1.0,   0.1,
7609          1.0,   -1.0,   0.1,
7610         -1.0,    0.0,   0.1,
7611
7612          1.0,   -1.0,   0.1,
7613          1.0,    0.0,   0.1,
7614         -1.0,    0.0,   0.1,
7615
7616         -1.0,    0.0,   0.1,
7617         -1.0,    1.0,   0.1,
7618          1.0,    0.0,   0.1,
7619
7620          1.0,    0.0,   0.1,
7621         -1.0,    1.0,   0.1,
7622          1.0,    1.0,   0.1,
7623     };
7624     const float blit[] = {
7625          0.0,   -1.0,   0.1,    0.0,    0.0,
7626          1.0,   -1.0,   0.1,    1.0,    0.0,
7627          0.0,    1.0,   0.1,    0.0,    1.0,
7628          1.0,    1.0,   0.1,    1.0,    1.0,
7629     };
7630
7631     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7632     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7633     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7634     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7635     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7636     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7637     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7638     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7639     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7640     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7641     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7642     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7643
7644     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7645     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7646
7647     hr = IDirect3DDevice9_BeginScene(device);
7648     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7649     if(SUCCEEDED(hr)) {
7650         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7651         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7652         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7653         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7654         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7655         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7656         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7657         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7658         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7659         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7660         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7661
7662         /* Blit the texture onto the back buffer to make it visible */
7663         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7664         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7665         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7666         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7667         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7668         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7669         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7670         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7671         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7672         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7673
7674         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7675         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7676
7677         hr = IDirect3DDevice9_EndScene(device);
7678         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7679     }
7680
7681     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7682     color = getPixelColor(device, 160, 360);
7683     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7684     color = getPixelColor(device, 160, 120);
7685     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7686     color = getPixelColor(device, 480, 360);
7687     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7688     color = getPixelColor(device, 480, 120);
7689     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7690
7691     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7692     IDirect3DDevice9_SetTexture(device, 0, NULL);
7693     IDirect3DPixelShader9_Release(shader);
7694     IDirect3DSurface9_Release(surface);
7695     IDirect3DSurface9_Release(backbuffer);
7696     IDirect3DTexture9_Release(texture);
7697 }
7698
7699 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7700 {
7701     HRESULT hr;
7702     DWORD color;
7703     int i;
7704     D3DCAPS9 caps;
7705
7706     static const float quad[][7] = {
7707         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7708         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7709         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7710         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7711     };
7712
7713     static const D3DVERTEXELEMENT9 decl_elements[] = {
7714         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7715         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7716         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7717         D3DDECL_END()
7718     };
7719
7720     /* use asymmetric matrix to test loading */
7721     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7722
7723     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7724     IDirect3DTexture9           *texture            = NULL;
7725
7726     memset(&caps, 0, sizeof(caps));
7727     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7728     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7729     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7730         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7731         return;
7732     } else {
7733         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7734          * They report that it is not supported, but after that bump mapping works properly. So just test
7735          * if the format is generally supported, and check the BUMPENVMAP flag
7736          */
7737         IDirect3D9 *d3d9;
7738
7739         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7740         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7741                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7742         IDirect3D9_Release(d3d9);
7743         if(FAILED(hr)) {
7744             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7745             return;
7746         }
7747     }
7748
7749     /* Generate the textures */
7750     generate_bumpmap_textures(device);
7751
7752     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7753     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7754     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7755     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7756     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7757     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7758     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7759     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7760
7761     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7762     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7763     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7764     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7765     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7766     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7767
7768     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7769     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7770     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7771     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7772     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7773     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7774
7775     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7776     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7777
7778     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7779     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7780
7781     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7782     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7783
7784
7785     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7786     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7787     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7788     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7789
7790     hr = IDirect3DDevice9_BeginScene(device);
7791     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7792
7793     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7794     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7795
7796     hr = IDirect3DDevice9_EndScene(device);
7797     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7798
7799     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7800     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7801
7802     color = getPixelColor(device, 320-32, 240);
7803     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7804     color = getPixelColor(device, 320+32, 240);
7805     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7806     color = getPixelColor(device, 320, 240-32);
7807     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7808     color = getPixelColor(device, 320, 240+32);
7809     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7810     color = getPixelColor(device, 320, 240);
7811     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7812     color = getPixelColor(device, 320+32, 240+32);
7813     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7814     color = getPixelColor(device, 320-32, 240+32);
7815     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7816     color = getPixelColor(device, 320+32, 240-32);
7817     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7818     color = getPixelColor(device, 320-32, 240-32);
7819     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7820
7821     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7822     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7823     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7824
7825     for(i = 0; i < 2; i++) {
7826         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7827         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7828         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7829         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7830         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7831         IDirect3DTexture9_Release(texture); /* To destroy it */
7832     }
7833
7834     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7835     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7836     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7837     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7838
7839 }
7840
7841 static void stencil_cull_test(IDirect3DDevice9 *device) {
7842     HRESULT hr;
7843     IDirect3DSurface9 *depthstencil = NULL;
7844     D3DSURFACE_DESC desc;
7845     float quad1[] = {
7846         -1.0,   -1.0,   0.1,
7847          0.0,   -1.0,   0.1,
7848         -1.0,    0.0,   0.1,
7849          0.0,    0.0,   0.1,
7850     };
7851     float quad2[] = {
7852          0.0,   -1.0,   0.1,
7853          1.0,   -1.0,   0.1,
7854          0.0,    0.0,   0.1,
7855          1.0,    0.0,   0.1,
7856     };
7857     float quad3[] = {
7858         0.0,    0.0,   0.1,
7859         1.0,    0.0,   0.1,
7860         0.0,    1.0,   0.1,
7861         1.0,    1.0,   0.1,
7862     };
7863     float quad4[] = {
7864         -1.0,    0.0,   0.1,
7865          0.0,    0.0,   0.1,
7866         -1.0,    1.0,   0.1,
7867          0.0,    1.0,   0.1,
7868     };
7869     struct vertex painter[] = {
7870        {-1.0,   -1.0,   0.0,    0x00000000},
7871        { 1.0,   -1.0,   0.0,    0x00000000},
7872        {-1.0,    1.0,   0.0,    0x00000000},
7873        { 1.0,    1.0,   0.0,    0x00000000},
7874     };
7875     WORD indices_cw[]  = {0, 1, 3};
7876     WORD indices_ccw[] = {0, 2, 3};
7877     unsigned int i;
7878     DWORD color;
7879
7880     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7881     if(depthstencil == NULL) {
7882         skip("No depth stencil buffer\n");
7883         return;
7884     }
7885     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7886     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7887     IDirect3DSurface9_Release(depthstencil);
7888     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7889         skip("No 4 or 8 bit stencil surface\n");
7890         return;
7891     }
7892
7893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7894     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7895     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7896
7897     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7898     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7899     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7900     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7901     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7902     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7903     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7904     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7905
7906     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7907     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7908     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7909     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7910     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7911     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7912
7913     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7914     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7915     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7916     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7917
7918     /* First pass: Fill the stencil buffer with some values... */
7919     hr = IDirect3DDevice9_BeginScene(device);
7920     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7921     if(SUCCEEDED(hr))
7922     {
7923         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7924         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7925         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7926                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7927         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7928                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7929
7930         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7931         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7932         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7933         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7934         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7935                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7936         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7937                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7938
7939         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7940         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7941         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7942                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7943         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7944                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7945
7946         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7947         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7948         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7949                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7950         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7951                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7952
7953         hr = IDirect3DDevice9_EndScene(device);
7954         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7955     }
7956
7957     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7958     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7959     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7960     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7961     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7962     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7963     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7964     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7965     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7966     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7967     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7969     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7970
7971     /* 2nd pass: Make the stencil values visible */
7972     hr = IDirect3DDevice9_BeginScene(device);
7973     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7974     if(SUCCEEDED(hr))
7975     {
7976         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7977         for(i = 0; i < 16; i++) {
7978             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7979             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7980
7981             painter[0].diffuse = (i * 16); /* Creates shades of blue */
7982             painter[1].diffuse = (i * 16);
7983             painter[2].diffuse = (i * 16);
7984             painter[3].diffuse = (i * 16);
7985             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7986             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7987         }
7988         hr = IDirect3DDevice9_EndScene(device);
7989         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7990     }
7991
7992     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7993     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7994
7995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7996     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7997
7998     color = getPixelColor(device, 160, 420);
7999     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8000     color = getPixelColor(device, 160, 300);
8001     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8002
8003     color = getPixelColor(device, 480, 420);
8004     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8005     color = getPixelColor(device, 480, 300);
8006     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8007
8008     color = getPixelColor(device, 160, 180);
8009     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8010     color = getPixelColor(device, 160, 60);
8011     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8012
8013     color = getPixelColor(device, 480, 180);
8014     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8015     color = getPixelColor(device, 480, 60);
8016     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8017 }
8018
8019 static void vpos_register_test(IDirect3DDevice9 *device)
8020 {
8021     HRESULT hr;
8022     DWORD color;
8023     const DWORD shader_code[] = {
8024     0xffff0300,                                                             /* ps_3_0                     */
8025     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8026     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8027     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8028     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8029     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8030     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8031     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8032     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8033     0x0000ffff                                                              /* end                        */
8034     };
8035     const DWORD shader_frac_code[] = {
8036     0xffff0300,                                                             /* ps_3_0                     */
8037     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8038     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8039     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8040     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8041     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8042     0x0000ffff                                                              /* end                        */
8043     };
8044     IDirect3DPixelShader9 *shader, *shader_frac;
8045     IDirect3DSurface9 *surface = NULL, *backbuffer;
8046     const float quad[] = {
8047         -1.0,   -1.0,   0.1,    0.0,    0.0,
8048          1.0,   -1.0,   0.1,    1.0,    0.0,
8049         -1.0,    1.0,   0.1,    0.0,    1.0,
8050          1.0,    1.0,   0.1,    1.0,    1.0,
8051     };
8052     D3DLOCKED_RECT lr;
8053     float constant[4] = {1.0, 0.0, 320, 240};
8054     DWORD *pos;
8055
8056     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8057     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8058     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8059     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8060     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8061     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8062     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8064     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8065     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8066     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8067     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8068
8069     hr = IDirect3DDevice9_BeginScene(device);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8071     if(SUCCEEDED(hr)) {
8072         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8073         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8074         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8075         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8076         hr = IDirect3DDevice9_EndScene(device);
8077         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8078     }
8079
8080     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8081     /* This has to be pixel exact */
8082     color = getPixelColor(device, 319, 239);
8083     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8084     color = getPixelColor(device, 320, 239);
8085     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8086     color = getPixelColor(device, 319, 240);
8087     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8088     color = getPixelColor(device, 320, 240);
8089     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8090
8091     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8092                                              &surface, NULL);
8093     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8094     hr = IDirect3DDevice9_BeginScene(device);
8095     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8096     if(SUCCEEDED(hr)) {
8097         constant[2] = 16; constant[3] = 16;
8098         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8099         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8100         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8101         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8102         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8103         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8104         hr = IDirect3DDevice9_EndScene(device);
8105         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8106     }
8107     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8108     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8109
8110     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8111     color = *pos & 0x00ffffff;
8112     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8113     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8114     color = *pos & 0x00ffffff;
8115     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8116     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8117     color = *pos & 0x00ffffff;
8118     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8119     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8120     color = *pos & 0x00ffffff;
8121     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8122
8123     hr = IDirect3DSurface9_UnlockRect(surface);
8124     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8125
8126     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8127      * have full control over the multisampling setting inside this test
8128      */
8129     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8130     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8131     hr = IDirect3DDevice9_BeginScene(device);
8132     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8133     if(SUCCEEDED(hr)) {
8134         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8135         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8137         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8138         hr = IDirect3DDevice9_EndScene(device);
8139         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8140     }
8141     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8142     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8143
8144     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8145     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8146
8147     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8148     color = *pos & 0x00ffffff;
8149     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8150
8151     hr = IDirect3DSurface9_UnlockRect(surface);
8152     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8153
8154     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8156     IDirect3DPixelShader9_Release(shader);
8157     IDirect3DPixelShader9_Release(shader_frac);
8158     if(surface) IDirect3DSurface9_Release(surface);
8159     IDirect3DSurface9_Release(backbuffer);
8160 }
8161
8162 static void pointsize_test(IDirect3DDevice9 *device)
8163 {
8164     HRESULT hr;
8165     D3DCAPS9 caps;
8166     D3DMATRIX matrix;
8167     D3DMATRIX identity;
8168     float ptsize, ptsize_orig;
8169     DWORD color;
8170
8171     const float vertices[] = {
8172         64,     64,     0.1,
8173         128,    64,     0.1,
8174         192,    64,     0.1,
8175         256,    64,     0.1,
8176         320,    64,     0.1,
8177         384,    64,     0.1
8178     };
8179
8180     /* 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 */
8181     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;
8182     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;
8183     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;
8184     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;
8185
8186     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;
8187     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;
8188     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;
8189     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;
8190
8191     memset(&caps, 0, sizeof(caps));
8192     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8193     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8194     if(caps.MaxPointSize < 32.0) {
8195         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8196         return;
8197     }
8198
8199     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8200     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8201     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8202     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8203     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8204     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8205     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8206     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8207
8208     hr = IDirect3DDevice9_BeginScene(device);
8209     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8210     if(SUCCEEDED(hr)) {
8211         ptsize = 16.0;
8212         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8213         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8214         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8215         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8216
8217         ptsize = 32.0;
8218         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8219         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8220         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8221         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8222
8223         ptsize = 31.5;
8224         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8225         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8226         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8227         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8228
8229         if(caps.MaxPointSize >= 64.0) {
8230             ptsize = 64.0;
8231             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8232             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8233             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8234             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8235
8236             ptsize = 63.75;
8237             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8238             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8239             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8240             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8241         }
8242
8243         ptsize = 1.0;
8244         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8245         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8246         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8247         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8248
8249         hr = IDirect3DDevice9_EndScene(device);
8250         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8251     }
8252     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8253     color = getPixelColor(device, 64-9, 64-9);
8254     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8255     color = getPixelColor(device, 64-8, 64-8);
8256     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8257     color = getPixelColor(device, 64-7, 64-7);
8258     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8259     color = getPixelColor(device, 64+7, 64+7);
8260     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8261     color = getPixelColor(device, 64+8, 64+8);
8262     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8263     color = getPixelColor(device, 64+9, 64+9);
8264     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8265
8266     color = getPixelColor(device, 128-17, 64-17);
8267     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8268     color = getPixelColor(device, 128-16, 64-16);
8269     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8270     color = getPixelColor(device, 128-15, 64-15);
8271     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8272     color = getPixelColor(device, 128+15, 64+15);
8273     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8274     color = getPixelColor(device, 128+16, 64+16);
8275     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8276     color = getPixelColor(device, 128+17, 64+17);
8277     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8278
8279     color = getPixelColor(device, 192-17, 64-17);
8280     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8281     color = getPixelColor(device, 192-16, 64-16);
8282     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8283     color = getPixelColor(device, 192-15, 64-15);
8284     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8285     color = getPixelColor(device, 192+15, 64+15);
8286     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8287     color = getPixelColor(device, 192+16, 64+16);
8288     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8289     color = getPixelColor(device, 192+17, 64+17);
8290     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8291
8292     if(caps.MaxPointSize >= 64.0) {
8293         color = getPixelColor(device, 256-33, 64-33);
8294         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8295         color = getPixelColor(device, 256-32, 64-32);
8296         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8297         color = getPixelColor(device, 256-31, 64-31);
8298         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8299         color = getPixelColor(device, 256+31, 64+31);
8300         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8301         color = getPixelColor(device, 256+32, 64+32);
8302         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8303         color = getPixelColor(device, 256+33, 64+33);
8304         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8305
8306         color = getPixelColor(device, 384-33, 64-33);
8307         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8308         color = getPixelColor(device, 384-32, 64-32);
8309         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8310         color = getPixelColor(device, 384-31, 64-31);
8311         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8312         color = getPixelColor(device, 384+31, 64+31);
8313         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8314         color = getPixelColor(device, 384+32, 64+32);
8315         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8316         color = getPixelColor(device, 384+33, 64+33);
8317         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8318     }
8319
8320     color = getPixelColor(device, 320-1, 64-1);
8321     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8322     color = getPixelColor(device, 320-0, 64-0);
8323     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8324     color = getPixelColor(device, 320+1, 64+1);
8325     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8326
8327     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8328     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8329     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8330     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8331 }
8332
8333 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8334 {
8335     HRESULT hr;
8336     IDirect3DPixelShader9 *ps;
8337     IDirect3DTexture9 *tex1, *tex2;
8338     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8339     D3DCAPS9 caps;
8340     DWORD color;
8341     DWORD shader_code[] = {
8342     0xffff0300,                                                             /* ps_3_0             */
8343     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8344     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8345     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8346     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8347     0x0000ffff                                                              /* END                */
8348     };
8349     float quad[] = {
8350        -1.0,   -1.0,    0.1,
8351         1.0,   -1.0,    0.1,
8352        -1.0,    1.0,    0.1,
8353         1.0,    1.0,    0.1,
8354     };
8355     float texquad[] = {
8356        -1.0,   -1.0,    0.1,    0.0,    0.0,
8357         0.0,   -1.0,    0.1,    1.0,    0.0,
8358        -1.0,    1.0,    0.1,    0.0,    1.0,
8359         0.0,    1.0,    0.1,    1.0,    1.0,
8360
8361         0.0,   -1.0,    0.1,    0.0,    0.0,
8362         1.0,   -1.0,    0.1,    1.0,    0.0,
8363         0.0,    1.0,    0.1,    0.0,    1.0,
8364         1.0,    1.0,    0.1,    1.0,    1.0,
8365     };
8366
8367     memset(&caps, 0, sizeof(caps));
8368     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8369     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8370     if(caps.NumSimultaneousRTs < 2) {
8371         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8372         return;
8373     }
8374
8375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8377
8378     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8379     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8380     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8381     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8382     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8383     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8384
8385     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8386     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8387     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8388     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8389     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8390     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8391
8392     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8393     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8394     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8395     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8396     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8397     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8398     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8399     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8400
8401     hr = IDirect3DDevice9_BeginScene(device);
8402     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8403     if(SUCCEEDED(hr)) {
8404         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8405         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8406
8407         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8408         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8409         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8410         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8411         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8412         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8413         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8414         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8415
8416         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8417         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8418         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8419         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8420
8421         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8422         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8423         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8424         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8425
8426         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8427         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8428
8429         hr = IDirect3DDevice9_EndScene(device);
8430         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8431     }
8432
8433     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8434     color = getPixelColor(device, 160, 240);
8435     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8436     color = getPixelColor(device, 480, 240);
8437     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8438
8439     IDirect3DPixelShader9_Release(ps);
8440     IDirect3DTexture9_Release(tex1);
8441     IDirect3DTexture9_Release(tex2);
8442     IDirect3DSurface9_Release(surf1);
8443     IDirect3DSurface9_Release(surf2);
8444     IDirect3DSurface9_Release(backbuf);
8445 }
8446
8447 struct formats {
8448     const char *fmtName;
8449     D3DFORMAT textureFormat;
8450     DWORD resultColorBlending;
8451     DWORD resultColorNoBlending;
8452 };
8453
8454 const struct formats test_formats[] = {
8455   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8456   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8457   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8458   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8459   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8460   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8461   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8462   { NULL, 0 }
8463 };
8464
8465 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8466 {
8467     HRESULT hr;
8468     IDirect3DTexture9 *offscreenTexture = NULL;
8469     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8470     IDirect3D9 *d3d = NULL;
8471     DWORD color;
8472     DWORD r0, g0, b0, r1, g1, b1;
8473     int fmt_index;
8474
8475     static const float quad[][5] = {
8476         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8477         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8478         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8479         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8480     };
8481
8482     /* Quad with R=0x10, G=0x20 */
8483     static const struct vertex quad1[] = {
8484         {-1.0f, -1.0f, 0.1f, 0x80102000},
8485         {-1.0f,  1.0f, 0.1f, 0x80102000},
8486         { 1.0f, -1.0f, 0.1f, 0x80102000},
8487         { 1.0f,  1.0f, 0.1f, 0x80102000},
8488     };
8489
8490     /* Quad with R=0x20, G=0x10 */
8491     static const struct vertex quad2[] = {
8492         {-1.0f, -1.0f, 0.1f, 0x80201000},
8493         {-1.0f,  1.0f, 0.1f, 0x80201000},
8494         { 1.0f, -1.0f, 0.1f, 0x80201000},
8495         { 1.0f,  1.0f, 0.1f, 0x80201000},
8496     };
8497
8498     IDirect3DDevice9_GetDirect3D(device, &d3d);
8499
8500     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8501     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8502     if(!backbuffer) {
8503         goto out;
8504     }
8505
8506     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8507     {
8508         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8509         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8510            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8511            continue;
8512         }
8513
8514         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8515         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8516
8517         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8518         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8519         if(!offscreenTexture) {
8520             continue;
8521         }
8522
8523         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8524         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8525         if(!offscreen) {
8526             continue;
8527         }
8528
8529         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8530         ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8531
8532         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8533         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8534         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8535         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8536         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8537         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8538         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8539         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8540         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8541         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8542
8543         /* Below we will draw two quads with different colors and try to blend them together.
8544          * The result color is compared with the expected outcome.
8545          */
8546         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8547             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8548             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8549             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8550             ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8551
8552             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8553             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8554
8555             /* Draw a quad using color 0x0010200 */
8556             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8557             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8558             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8559             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8560             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8561             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8562
8563             /* Draw a quad using color 0x0020100 */
8564             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8565             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8566             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8567             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8568             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8569             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8570
8571             /* We don't want to blend the result on the backbuffer */
8572             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8573             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8574
8575             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8576             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8577             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8578             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8579             ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8580
8581             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8582             ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8583
8584             /* This time with the texture */
8585             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8586             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8587
8588             IDirect3DDevice9_EndScene(device);
8589         }
8590         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8591
8592
8593         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8594             /* Compare the color of the center quad with our expectation */
8595             color = getPixelColor(device, 320, 240);
8596             r0 = (color & 0x00ff0000) >> 16;
8597             g0 = (color & 0x0000ff00) >>  8;
8598             b0 = (color & 0x000000ff) >>  0;
8599
8600             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8601             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8602             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8603
8604             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8605                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8606                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8607                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8608         } else {
8609             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8610              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8611              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8612             color = getPixelColor(device, 320, 240);
8613             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);
8614         }
8615
8616         IDirect3DDevice9_SetTexture(device, 0, NULL);
8617         if(offscreenTexture) {
8618             IDirect3DTexture9_Release(offscreenTexture);
8619         }
8620         if(offscreen) {
8621             IDirect3DSurface9_Release(offscreen);
8622         }
8623     }
8624
8625 out:
8626     /* restore things */
8627     if(backbuffer) {
8628         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8629         IDirect3DSurface9_Release(backbuffer);
8630     }
8631 }
8632
8633 static void tssargtemp_test(IDirect3DDevice9 *device)
8634 {
8635     HRESULT hr;
8636     DWORD color;
8637     static const struct vertex quad[] = {
8638         {-1.0,     -1.0,    0.1,    0x00ff0000},
8639         { 1.0,     -1.0,    0.1,    0x00ff0000},
8640         {-1.0,      1.0,    0.1,    0x00ff0000},
8641         { 1.0,      1.0,    0.1,    0x00ff0000}
8642     };
8643     D3DCAPS9 caps;
8644
8645     memset(&caps, 0, sizeof(caps));
8646     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8648     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8649         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8650         return;
8651     }
8652
8653     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8654     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8655
8656     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8657     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8658     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8659     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8660
8661     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8662     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8663     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8664     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8665     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8666     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8667
8668     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8669     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8670     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8671     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8672     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8673     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8674
8675     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8676     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8677
8678     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8679     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8680     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8681     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8682
8683     hr = IDirect3DDevice9_BeginScene(device);
8684     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8685     if(SUCCEEDED(hr)) {
8686
8687         hr = IDirect3DDevice9_EndScene(device);
8688         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8690         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8691     }
8692     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8693     color = getPixelColor(device, 320, 240);
8694     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8695
8696     /* Set stage 1 back to default */
8697     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8698     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8699     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8700     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8701     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8702     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8703     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8704     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8705     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8706     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8707 }
8708
8709 struct testdata
8710 {
8711     DWORD idxVertex; /* number of instances in the first stream */
8712     DWORD idxColor; /* number of instances in the second stream */
8713     DWORD idxInstance; /* should be 1 ?? */
8714     DWORD color1; /* color 1 instance */
8715     DWORD color2; /* color 2 instance */
8716     DWORD color3; /* color 3 instance */
8717     DWORD color4; /* color 4 instance */
8718     WORD strVertex; /* specify which stream to use 0-2*/
8719     WORD strColor;
8720     WORD strInstance;
8721 };
8722
8723 static const struct testdata testcases[]=
8724 {
8725     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8726     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8727     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8728     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8729     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8730     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8731     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8732     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8733     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8734     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8735     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8736     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8737     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8738     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8739     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8740 /*
8741     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8742     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8743 */
8744 };
8745
8746 /* Drawing Indexed Geometry with instances*/
8747 static void stream_test(IDirect3DDevice9 *device)
8748 {
8749     IDirect3DVertexBuffer9 *vb = NULL;
8750     IDirect3DVertexBuffer9 *vb2 = NULL;
8751     IDirect3DVertexBuffer9 *vb3 = NULL;
8752     IDirect3DIndexBuffer9 *ib = NULL;
8753     IDirect3DVertexDeclaration9 *pDecl = NULL;
8754     IDirect3DVertexShader9 *shader = NULL;
8755     HRESULT hr;
8756     BYTE *data;
8757     DWORD color;
8758     DWORD ind;
8759     int i;
8760
8761     const DWORD shader_code[] =
8762     {
8763         0xfffe0101,                                     /* vs_1_1 */
8764         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
8765         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
8766         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
8767         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
8768         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8769         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
8770         0x0000ffff
8771     };
8772
8773     const float quad[][3] =
8774     {
8775         {-0.5f, -0.5f,  1.1f}, /*0 */
8776         {-0.5f,  0.5f,  1.1f}, /*1 */
8777         { 0.5f, -0.5f,  1.1f}, /*2 */
8778         { 0.5f,  0.5f,  1.1f}, /*3 */
8779     };
8780
8781     const float vertcolor[][4] =
8782     {
8783         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8784         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8785         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8786         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8787     };
8788
8789     /* 4 position for 4 instances */
8790     const float instancepos[][3] =
8791     {
8792         {-0.6f,-0.6f, 0.0f},
8793         { 0.6f,-0.6f, 0.0f},
8794         { 0.6f, 0.6f, 0.0f},
8795         {-0.6f, 0.6f, 0.0f},
8796     };
8797
8798     short indices[] = {0, 1, 2, 1, 2, 3};
8799
8800     D3DVERTEXELEMENT9 decl[] =
8801     {
8802         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8803         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8804         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8805         D3DDECL_END()
8806     };
8807
8808     /* set the default value because it isn't done in wine? */
8809     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8810     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8811
8812     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8813     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8814     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8815
8816     /* check wrong cases */
8817     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8818     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8819     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8820     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8821     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8822     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8823     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8824     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8825     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8826     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8827     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8828     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8829     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8830     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8831     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8832     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8833     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8834     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8835     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8836     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8837
8838     /* set the default value back */
8839     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8840     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8841
8842     /* create all VertexBuffers*/
8843     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8844     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8845     if(!vb) {
8846         skip("Failed to create a vertex buffer\n");
8847         return;
8848     }
8849     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8850     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8851     if(!vb2) {
8852         skip("Failed to create a vertex buffer\n");
8853         goto out;
8854     }
8855     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8856     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8857     if(!vb3) {
8858         skip("Failed to create a vertex buffer\n");
8859         goto out;
8860     }
8861
8862     /* create IndexBuffer*/
8863     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8864     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8865     if(!ib) {
8866         skip("Failed to create a index buffer\n");
8867         goto out;
8868     }
8869
8870     /* copy all Buffers (Vertex + Index)*/
8871     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8872     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8873     memcpy(data, quad, sizeof(quad));
8874     hr = IDirect3DVertexBuffer9_Unlock(vb);
8875     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8876     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8877     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8878     memcpy(data, vertcolor, sizeof(vertcolor));
8879     hr = IDirect3DVertexBuffer9_Unlock(vb2);
8880     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8881     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8882     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8883     memcpy(data, instancepos, sizeof(instancepos));
8884     hr = IDirect3DVertexBuffer9_Unlock(vb3);
8885     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8886     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8887     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8888     memcpy(data, indices, sizeof(indices));
8889     hr = IDirect3DIndexBuffer9_Unlock(ib);
8890     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8891
8892     /* create VertexShader */
8893     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8894     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8895     if(!shader) {
8896         skip("Failed to create a vetex shader\n");
8897         goto out;
8898     }
8899
8900     hr = IDirect3DDevice9_SetVertexShader(device, shader);
8901     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8902
8903     hr = IDirect3DDevice9_SetIndices(device, ib);
8904     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8905
8906     /* run all tests */
8907     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8908     {
8909         struct testdata act = testcases[i];
8910         decl[0].Stream = act.strVertex;
8911         decl[1].Stream = act.strColor;
8912         decl[2].Stream = act.strInstance;
8913         /* create VertexDeclarations */
8914         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8915         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8916
8917         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8918         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8919
8920         hr = IDirect3DDevice9_BeginScene(device);
8921         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8922         if(SUCCEEDED(hr))
8923         {
8924             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8925             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8926
8927             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8928             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8929             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8930             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8931
8932             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8933             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8934             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8935             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8936
8937             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8938             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8939             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8940             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8941
8942             /* don't know if this is right (1*3 and 4*1)*/
8943             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8944             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8945             hr = IDirect3DDevice9_EndScene(device);
8946             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8947
8948             /* set all StreamSource && StreamSourceFreq back to default */
8949             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8950             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8951             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8952             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8953             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8954             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8955             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8956             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8957             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8958             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8959             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8960             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8961         }
8962
8963         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8964         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8965
8966         hr = IDirect3DVertexDeclaration9_Release(pDecl);
8967         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8968
8969         color = getPixelColor(device, 160, 360);
8970         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8971         color = getPixelColor(device, 480, 360);
8972         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8973         color = getPixelColor(device, 480, 120);
8974         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8975         color = getPixelColor(device, 160, 120);
8976         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8977     }
8978
8979     hr = IDirect3DDevice9_SetIndices(device, NULL);
8980     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8981
8982 out:
8983     if(vb) IDirect3DVertexBuffer9_Release(vb);
8984     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8985     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8986     if(ib)IDirect3DIndexBuffer9_Release(ib);
8987     if(shader)IDirect3DVertexShader9_Release(shader);
8988 }
8989
8990 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8991     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8992     IDirect3DTexture9 *dsttex = NULL;
8993     HRESULT hr;
8994     DWORD color;
8995     D3DRECT r1 = {0,  0,  50,  50 };
8996     D3DRECT r2 = {50, 0,  100, 50 };
8997     D3DRECT r3 = {50, 50, 100, 100};
8998     D3DRECT r4 = {0,  50,  50, 100};
8999     const float quad[] = {
9000         -1.0,   -1.0,   0.1,    0.0,    0.0,
9001          1.0,   -1.0,   0.1,    1.0,    0.0,
9002         -1.0,    1.0,   0.1,    0.0,    1.0,
9003          1.0,    1.0,   0.1,    1.0,    1.0,
9004     };
9005
9006     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9007     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
9008
9009     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9010     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
9011     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9012     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
9013
9014     if(!src || !dsttex) {
9015         skip("One or more test resources could not be created\n");
9016         goto cleanup;
9017     }
9018
9019     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9020     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
9021
9022     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9024
9025     /* Clear the StretchRect destination for debugging */
9026     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9027     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9028     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9029     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9030
9031     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9032     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9033
9034     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9035     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9036     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9037     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9038     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9039     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9040     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9041     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9042
9043     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9044      * the target -> texture GL blit path
9045      */
9046     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9047     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9048     IDirect3DSurface9_Release(dst);
9049
9050     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9051     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9052
9053     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9054     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9055     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9056     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9057     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9058     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9059     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9060     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9061
9062     hr = IDirect3DDevice9_BeginScene(device);
9063     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9064     if(SUCCEEDED(hr)) {
9065         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9066         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9067         hr = IDirect3DDevice9_EndScene(device);
9068         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9069     }
9070
9071     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9072     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9073     color = getPixelColor(device, 160, 360);
9074     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9075     color = getPixelColor(device, 480, 360);
9076     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9077     color = getPixelColor(device, 480, 120);
9078     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9079     color = getPixelColor(device, 160, 120);
9080     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9081
9082     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9083     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9084     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9085     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9086
9087 cleanup:
9088     if(src) IDirect3DSurface9_Release(src);
9089     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9090     if(dsttex) IDirect3DTexture9_Release(dsttex);
9091 }
9092
9093 START_TEST(visual)
9094 {
9095     IDirect3DDevice9 *device_ptr;
9096     D3DCAPS9 caps;
9097     HRESULT hr;
9098     DWORD color;
9099
9100     d3d9_handle = LoadLibraryA("d3d9.dll");
9101     if (!d3d9_handle)
9102     {
9103         skip("Could not load d3d9.dll\n");
9104         return;
9105     }
9106
9107     device_ptr = init_d3d9();
9108     if (!device_ptr)
9109     {
9110         skip("Creating the device failed\n");
9111         return;
9112     }
9113
9114     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9115
9116     /* Check for the reliability of the returned data */
9117     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9118     if(FAILED(hr))
9119     {
9120         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9121         goto cleanup;
9122     }
9123     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9124
9125     color = getPixelColor(device_ptr, 1, 1);
9126     if(color !=0x00ff0000)
9127     {
9128         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9129         goto cleanup;
9130     }
9131
9132     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9133     if(FAILED(hr))
9134     {
9135         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9136         goto cleanup;
9137     }
9138     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9139
9140     color = getPixelColor(device_ptr, 639, 479);
9141     if(color != 0x0000ddee)
9142     {
9143         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9144         goto cleanup;
9145     }
9146
9147     /* Now execute the real tests */
9148     stretchrect_test(device_ptr);
9149     lighting_test(device_ptr);
9150     clear_test(device_ptr);
9151     fog_test(device_ptr);
9152     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9153     {
9154         test_cube_wrap(device_ptr);
9155     } else {
9156         skip("No cube texture support\n");
9157     }
9158     z_range_test(device_ptr);
9159     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9160     {
9161         maxmip_test(device_ptr);
9162     }
9163     else
9164     {
9165         skip("No mipmap support\n");
9166     }
9167     offscreen_test(device_ptr);
9168     alpha_test(device_ptr);
9169     shademode_test(device_ptr);
9170     srgbtexture_test(device_ptr);
9171     release_buffer_test(device_ptr);
9172     float_texture_test(device_ptr);
9173     g16r16_texture_test(device_ptr);
9174     pixelshader_blending_test(device_ptr);
9175     texture_transform_flags_test(device_ptr);
9176     autogen_mipmap_test(device_ptr);
9177     fixed_function_decl_test(device_ptr);
9178     conditional_np2_repeat_test(device_ptr);
9179     fixed_function_bumpmap_test(device_ptr);
9180     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9181         stencil_cull_test(device_ptr);
9182     } else {
9183         skip("No two sided stencil support\n");
9184     }
9185     pointsize_test(device_ptr);
9186     tssargtemp_test(device_ptr);
9187     np2_stretch_rect_test(device_ptr);
9188
9189     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9190     {
9191         test_constant_clamp_vs(device_ptr);
9192         test_compare_instructions(device_ptr);
9193     }
9194     else skip("No vs_1_1 support\n");
9195
9196     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9197     {
9198         test_mova(device_ptr);
9199         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9200             test_vshader_input(device_ptr);
9201             test_vshader_float16(device_ptr);
9202             stream_test(device_ptr);
9203         } else {
9204             skip("No vs_3_0 support\n");
9205         }
9206     }
9207     else skip("No vs_2_0 support\n");
9208
9209     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9210     {
9211         fog_with_shader_test(device_ptr);
9212         fog_srgbwrite_test(device_ptr);
9213     }
9214     else skip("No vs_1_1 and ps_1_1 support\n");
9215
9216     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9217     {
9218         texbem_test(device_ptr);
9219         texdepth_test(device_ptr);
9220         texkill_test(device_ptr);
9221         x8l8v8u8_test(device_ptr);
9222         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9223             constant_clamp_ps_test(device_ptr);
9224             cnd_test(device_ptr);
9225             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9226                 dp2add_ps_test(device_ptr);
9227                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9228                     nested_loop_test(device_ptr);
9229                     fixed_function_varying_test(device_ptr);
9230                     vFace_register_test(device_ptr);
9231                     vpos_register_test(device_ptr);
9232                     multiple_rendertargets_test(device_ptr);
9233                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9234                         vshader_version_varying_test(device_ptr);
9235                         pshader_version_varying_test(device_ptr);
9236                     } else {
9237                         skip("No vs_3_0 support\n");
9238                     }
9239                 } else {
9240                     skip("No ps_3_0 support\n");
9241                 }
9242             } else {
9243                 skip("No ps_2_0 support\n");
9244             }
9245         }
9246     }
9247     else skip("No ps_1_1 support\n");
9248
9249 cleanup:
9250     if(device_ptr) {
9251         ULONG ref;
9252
9253         D3DPRESENT_PARAMETERS present_parameters;
9254         IDirect3DSwapChain9 *swapchain;
9255         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9256         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9257         IDirect3DSwapChain9_Release(swapchain);
9258         ref = IDirect3DDevice9_Release(device_ptr);
9259         DestroyWindow(present_parameters.hDeviceWindow);
9260         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
9261     }
9262 }