d3d9: Make the offscreen format test a bit more tolerant.
[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
147     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
148     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
149     if (!d3d9_create) return NULL;
150
151     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
152     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
153     if (!d3d9_ptr) return NULL;
154
155     ZeroMemory(&present_parameters, sizeof(present_parameters));
156     present_parameters.Windowed = FALSE;
157     present_parameters.hDeviceWindow = create_window();
158     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
159     present_parameters.BackBufferWidth = 640;
160     present_parameters.BackBufferHeight = 480;
161     present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
162     present_parameters.EnableAutoDepthStencil = TRUE;
163     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
164
165     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
166     if(FAILED(hr)) {
167         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
168         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
169         if(FAILED(hr)) {
170             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
171         }
172     }
173     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
174
175     return device_ptr;
176 }
177
178 struct vertex
179 {
180     float x, y, z;
181     DWORD diffuse;
182 };
183
184 struct tvertex
185 {
186     float x, y, z, rhw;
187     DWORD diffuse;
188 };
189
190 struct nvertex
191 {
192     float x, y, z;
193     float nx, ny, nz;
194     DWORD diffuse;
195 };
196
197 static void lighting_test(IDirect3DDevice9 *device)
198 {
199     HRESULT hr;
200     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
201     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
202     DWORD color;
203
204     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
205                       0.0f, 1.0f, 0.0f, 0.0f,
206                       0.0f, 0.0f, 1.0f, 0.0f,
207                       0.0f, 0.0f, 0.0f, 1.0f };
208
209     struct vertex unlitquad[] =
210     {
211         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
212         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
213         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
214         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
215     };
216     struct vertex litquad[] =
217     {
218         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
219         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
220         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
221         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
222     };
223     struct nvertex unlitnquad[] =
224     {
225         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
226         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
227         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
228         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
229     };
230     struct nvertex litnquad[] =
231     {
232         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
233         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
234         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
235         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
236     };
237     WORD Indices[] = {0, 1, 2, 2, 3, 0};
238
239     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
240     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
241
242     /* Setup some states that may cause issues */
243     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
244     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
245     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
246     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
247     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
248     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
249     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
250     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
251     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
252     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
253     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
254     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
255     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
256     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
257     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
258     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
259     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
260     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
261     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
262     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
263     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
264     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
265     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
266     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
267
268     hr = IDirect3DDevice9_SetFVF(device, fvf);
269     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
270
271     hr = IDirect3DDevice9_BeginScene(device);
272     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
273     if(hr == D3D_OK)
274     {
275         /* No lights are defined... That means, lit vertices should be entirely black */
276         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
277         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
278         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
279                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
280         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
281
282         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
283         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
284         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
285                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
286         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
287
288         hr = IDirect3DDevice9_SetFVF(device, nfvf);
289         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
290
291         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
292         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
293         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
294                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
295         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
296
297         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
298         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
299         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
300                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
301         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
302
303         IDirect3DDevice9_EndScene(device);
304         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
305     }
306
307     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
308
309     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
310     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
311     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
312     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
313     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
314     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
315     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
316     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
317
318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
320 }
321
322 static void clear_test(IDirect3DDevice9 *device)
323 {
324     /* Tests the correctness of clearing parameters */
325     HRESULT hr;
326     D3DRECT rect[2];
327     D3DRECT rect_negneg;
328     DWORD color;
329     D3DVIEWPORT9 old_vp, vp;
330     RECT scissor;
331     DWORD oldColorWrite;
332     BOOL invalid_clear_failed = FALSE;
333
334     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
335     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
336
337     /* Positive x, negative y */
338     rect[0].x1 = 0;
339     rect[0].y1 = 480;
340     rect[0].x2 = 320;
341     rect[0].y2 = 240;
342
343     /* Positive x, positive y */
344     rect[1].x1 = 0;
345     rect[1].y1 = 0;
346     rect[1].x2 = 320;
347     rect[1].y2 = 240;
348     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
349      * returns D3D_OK, but ignores the rectangle silently
350      */
351     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
352     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
353     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
354
355     /* negative x, negative y */
356     rect_negneg.x1 = 640;
357     rect_negneg.y1 = 240;
358     rect_negneg.x2 = 320;
359     rect_negneg.y2 = 0;
360     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
361     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
362     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
363
364     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
365
366     color = getPixelColor(device, 160, 360); /* lower left quad */
367     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
368     color = getPixelColor(device, 160, 120); /* upper left quad */
369     if(invalid_clear_failed) {
370         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
371         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
372     } else {
373         /* If the negative rectangle was dropped silently, the correct ones are cleared */
374         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
375     }
376     color = getPixelColor(device, 480, 360); /* lower right quad  */
377     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
378     color = getPixelColor(device, 480, 120); /* upper right quad */
379     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
380
381     /* Test how the viewport affects clears */
382     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
383     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
384     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
385     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
386
387     vp.X = 160;
388     vp.Y = 120;
389     vp.Width = 160;
390     vp.Height = 120;
391     vp.MinZ = 0.0;
392     vp.MaxZ = 1.0;
393     hr = IDirect3DDevice9_SetViewport(device, &vp);
394     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
395     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
396     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
397
398     vp.X = 320;
399     vp.Y = 240;
400     vp.Width = 320;
401     vp.Height = 240;
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     rect[0].x1 = 160;
407     rect[0].y1 = 120;
408     rect[0].x2 = 480;
409     rect[0].y2 = 360;
410     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
411     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
412
413     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
414     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
415
416     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
417     color = getPixelColor(device, 158, 118);
418     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
419     color = getPixelColor(device, 162, 118);
420     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
421     color = getPixelColor(device, 158, 122);
422     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
423     color = getPixelColor(device, 162, 122);
424     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
425
426     color = getPixelColor(device, 318, 238);
427     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
428     color = getPixelColor(device, 322, 238);
429     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
430     color = getPixelColor(device, 318, 242);
431     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
432     color = getPixelColor(device, 322, 242);
433     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
434
435     color = getPixelColor(device, 478, 358);
436     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
437     color = getPixelColor(device, 482, 358);
438     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
439     color = getPixelColor(device, 478, 362);
440     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
441     color = getPixelColor(device, 482, 362);
442     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
443
444     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
445     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
446
447     scissor.left = 160;
448     scissor.right = 480;
449     scissor.top = 120;
450     scissor.bottom = 360;
451     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
452     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
453     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
454     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
455
456     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
457     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
458     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
459     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
460
461     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
462     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
463
464     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
465     color = getPixelColor(device, 158, 118);
466     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
467     color = getPixelColor(device, 162, 118);
468     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
469     color = getPixelColor(device, 158, 122);
470     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
471     color = getPixelColor(device, 162, 122);
472     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
473
474     color = getPixelColor(device, 158, 358);
475     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
476     color = getPixelColor(device, 162, 358);
477     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
478     color = getPixelColor(device, 158, 358);
479     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
480     color = getPixelColor(device, 162, 362);
481     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
482
483     color = getPixelColor(device, 478, 118);
484     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
485     color = getPixelColor(device, 478, 122);
486     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
487     color = getPixelColor(device, 482, 122);
488     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
489     color = getPixelColor(device, 482, 358);
490     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
491
492     color = getPixelColor(device, 478, 358);
493     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
494     color = getPixelColor(device, 478, 362);
495     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
496     color = getPixelColor(device, 482, 358);
497     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
498     color = getPixelColor(device, 482, 362);
499     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
500
501     color = getPixelColor(device, 318, 238);
502     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
503     color = getPixelColor(device, 318, 242);
504     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
505     color = getPixelColor(device, 322, 238);
506     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
507     color = getPixelColor(device, 322, 242);
508     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
509
510     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
511     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
513     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
514
515     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
516     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
517
518     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
519     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
520
521     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
522
523     /* Colorwriteenable does not affect the clear */
524     color = getPixelColor(device, 320, 240);
525     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
526 }
527
528 typedef struct {
529     float in[4];
530     DWORD out;
531 } test_data_t;
532
533 /*
534  *  c7      mova    ARGB            mov     ARGB
535  * -2.4     -2      0x00ffff00      -3      0x00ff0000
536  * -1.6     -2      0x00ffff00      -2      0x00ffff00
537  * -0.4      0      0x0000ffff      -1      0x0000ff00
538  *  0.4      0      0x0000ffff       0      0x0000ffff
539  *  1.6      2      0x00ff00ff       1      0x000000ff
540  *  2.4      2      0x00ff00ff       2      0x00ff00ff
541  */
542 static void test_mova(IDirect3DDevice9 *device)
543 {
544     static const DWORD mova_test[] = {
545         0xfffe0200,                                                             /* vs_2_0                       */
546         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
547         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
548         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
549         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
550         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
551         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
552         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
553         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
554         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
555         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
556         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
557         0x0000ffff                                                              /* END                          */
558     };
559     static const DWORD mov_test[] = {
560         0xfffe0101,                                                             /* vs_1_1                       */
561         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
562         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
563         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
564         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
565         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
566         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
567         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
568         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
569         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
570         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
571         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
572         0x0000ffff                                                              /* END                          */
573     };
574
575     static const test_data_t test_data[2][6] = {
576         {
577             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
578             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
579             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
580             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
581             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
582             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
583         },
584         {
585             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
586             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
587             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
588             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
589             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
590             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
591         }
592     };
593
594     static const float quad[][3] = {
595         {-1.0f, -1.0f, 0.0f},
596         {-1.0f,  1.0f, 0.0f},
597         { 1.0f, -1.0f, 0.0f},
598         { 1.0f,  1.0f, 0.0f},
599     };
600
601     static const D3DVERTEXELEMENT9 decl_elements[] = {
602         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
603         D3DDECL_END()
604     };
605
606     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
607     IDirect3DVertexShader9 *mova_shader = NULL;
608     IDirect3DVertexShader9 *mov_shader = NULL;
609     HRESULT hr;
610     UINT i, j;
611
612     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
613     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
614     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
615     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
616     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
617     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
618     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
619     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
620
621     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
622     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
623     for(j = 0; j < 2; ++j)
624     {
625         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
626         {
627             DWORD color;
628
629             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
630             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
631
632             hr = IDirect3DDevice9_BeginScene(device);
633             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
634
635             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
636             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
637
638             hr = IDirect3DDevice9_EndScene(device);
639             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
640
641             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
642             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
643
644             color = getPixelColor(device, 320, 240);
645             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
646                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
647
648             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
649             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
650         }
651         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
652         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
653     }
654
655     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
656     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
657
658     IDirect3DVertexDeclaration9_Release(vertex_declaration);
659     IDirect3DVertexShader9_Release(mova_shader);
660     IDirect3DVertexShader9_Release(mov_shader);
661 }
662
663 struct sVertex {
664     float x, y, z;
665     DWORD diffuse;
666     DWORD specular;
667 };
668
669 struct sVertexT {
670     float x, y, z, rhw;
671     DWORD diffuse;
672     DWORD specular;
673 };
674
675 static void fog_test(IDirect3DDevice9 *device)
676 {
677     HRESULT hr;
678     DWORD color;
679     BYTE r, g, b;
680     float start = 0.0f, end = 1.0f;
681     D3DCAPS9 caps;
682     int i;
683
684     /* Gets full z based fog with linear fog, no fog with specular color */
685     struct sVertex unstransformed_1[] = {
686         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
687         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
688         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
689         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
690     };
691     /* Ok, I am too lazy to deal with transform matrices */
692     struct sVertex unstransformed_2[] = {
693         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
694         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
695         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
696         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
697     };
698     /* Untransformed ones. Give them a different diffuse color to make the test look
699      * nicer. It also makes making sure that they are drawn correctly easier.
700      */
701     struct sVertexT transformed_1[] = {
702         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
703         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
704         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
705         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
706     };
707     struct sVertexT transformed_2[] = {
708         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
709         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
710         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
711         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
712     };
713     struct vertex rev_fog_quads[] = {
714        {-1.0,   -1.0,   0.1,    0x000000ff},
715        {-1.0,    0.0,   0.1,    0x000000ff},
716        { 0.0,    0.0,   0.1,    0x000000ff},
717        { 0.0,   -1.0,   0.1,    0x000000ff},
718
719        { 0.0,   -1.0,   0.9,    0x000000ff},
720        { 0.0,    0.0,   0.9,    0x000000ff},
721        { 1.0,    0.0,   0.9,    0x000000ff},
722        { 1.0,   -1.0,   0.9,    0x000000ff},
723
724        { 0.0,    0.0,   0.4,    0x000000ff},
725        { 0.0,    1.0,   0.4,    0x000000ff},
726        { 1.0,    1.0,   0.4,    0x000000ff},
727        { 1.0,    0.0,   0.4,    0x000000ff},
728
729        {-1.0,    0.0,   0.7,    0x000000ff},
730        {-1.0,    1.0,   0.7,    0x000000ff},
731        { 0.0,    1.0,   0.7,    0x000000ff},
732        { 0.0,    0.0,   0.7,    0x000000ff},
733     };
734     WORD Indices[] = {0, 1, 2, 2, 3, 0};
735
736     memset(&caps, 0, sizeof(caps));
737     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
738     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
739     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
740     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
741
742     /* Setup initial states: No lighting, fog on, fog color */
743     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
744     ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
745     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
746     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
747     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
748     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
749
750     /* First test: Both table fog and vertex fog off */
751     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
752     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
753     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
754     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
755
756     /* Start = 0, end = 1. Should be default, but set them */
757     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
758     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
759     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
760     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
761
762     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
763     {
764         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
765         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
766         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
767         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
768                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
769                                                      sizeof(unstransformed_1[0]));
770         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
771
772         /* That makes it use the Z value */
773         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
774         ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
775         /* Untransformed, vertex fog != none (or table fog != none):
776          * Use the Z value as input into the equation
777          */
778         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
779                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
780                                                      sizeof(unstransformed_1[0]));
781         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
782
783         /* transformed verts */
784         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
785         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
786         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
787         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
788                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
789                                                      sizeof(transformed_1[0]));
790         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
791
792         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
793         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
794         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
795          * equation
796          */
797         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
798                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
799                                                      sizeof(transformed_2[0]));
800
801         hr = IDirect3DDevice9_EndScene(device);
802         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
803     }
804     else
805     {
806         ok(FALSE, "BeginScene failed\n");
807     }
808
809     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
810     color = getPixelColor(device, 160, 360);
811     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
812     color = getPixelColor(device, 160, 120);
813     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
814     color = getPixelColor(device, 480, 120);
815     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
816     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
817     {
818         color = getPixelColor(device, 480, 360);
819         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
820     }
821     else
822     {
823         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
824          * The settings above result in no fogging with vertex fog
825          */
826         color = getPixelColor(device, 480, 120);
827         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
828         trace("Info: Table fog not supported by this device\n");
829     }
830
831     /* Now test the special case fogstart == fogend */
832     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
833     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
834
835     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
836     {
837         start = 512;
838         end = 512;
839         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
840         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
841         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
842         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
843
844         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
845         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
846         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
847         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
848         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
849         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
850
851         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
852          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
853          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
854          * The third transformed quad remains unfogged because the fogcoords are read from the specular
855          * color and has fixed fogstart and fogend.
856          */
857         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
858                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
859                 sizeof(unstransformed_1[0]));
860         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
861         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
862                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
863                 sizeof(unstransformed_1[0]));
864         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
865
866         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
867         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
868         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
869         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
870                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
871                 sizeof(transformed_1[0]));
872         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
873
874         hr = IDirect3DDevice9_EndScene(device);
875         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
876     }
877     else
878     {
879         ok(FALSE, "BeginScene failed\n");
880     }
881     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
882     color = getPixelColor(device, 160, 360);
883     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
884     color = getPixelColor(device, 160, 120);
885     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
886     color = getPixelColor(device, 480, 120);
887     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
888
889     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
890      * but without shaders it seems to work everywhere
891      */
892     end = 0.2;
893     start = 0.8;
894     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
895     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
896     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
897     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
898     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
899     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
900
901     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
902      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
903      * so skip this for now
904      */
905     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
906         const char *mode = (i ? "table" : "vertex");
907         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
908         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
909         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
910         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
911         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
912         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
913         hr = IDirect3DDevice9_BeginScene(device);
914         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
915         if(SUCCEEDED(hr)) {
916             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
917                                 4,  5,  6,  6,  7, 4,
918                                 8,  9, 10, 10, 11, 8,
919                             12, 13, 14, 14, 15, 12};
920
921             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
922                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
923                     sizeof(rev_fog_quads[0]));
924
925             hr = IDirect3DDevice9_EndScene(device);
926             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
927         }
928         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
929         color = getPixelColor(device, 160, 360);
930         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
931
932         color = getPixelColor(device, 160, 120);
933         r = (color & 0x00ff0000) >> 16;
934         g = (color & 0x0000ff00) >>  8;
935         b = (color & 0x000000ff);
936         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
937            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
938
939         color = getPixelColor(device, 480, 120);
940         r = (color & 0x00ff0000) >> 16;
941         g = (color & 0x0000ff00) >>  8;
942         b = (color & 0x000000ff);
943         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
944            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
945
946         color = getPixelColor(device, 480, 360);
947         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
948
949         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
950             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
951             break;
952         }
953     }
954     /* Turn off the fog master switch to avoid confusing other tests */
955     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
956     ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
957     start = 0.0;
958     end = 1.0;
959     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
960     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
961     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
962     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
963     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
964     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
965     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
966     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
967 }
968
969 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
970  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
971  * regardless of the actual addressing mode set. */
972 static void test_cube_wrap(IDirect3DDevice9 *device)
973 {
974     static const float quad[][6] = {
975         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
976         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
977         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
978         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
979     };
980
981     static const D3DVERTEXELEMENT9 decl_elements[] = {
982         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
983         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
984         D3DDECL_END()
985     };
986
987     static const struct {
988         D3DTEXTUREADDRESS mode;
989         const char *name;
990     } address_modes[] = {
991         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
992         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
993         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
994         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
995         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
996     };
997
998     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
999     IDirect3DCubeTexture9 *texture = NULL;
1000     IDirect3DSurface9 *surface = NULL;
1001     D3DLOCKED_RECT locked_rect;
1002     HRESULT hr;
1003     UINT x;
1004     INT y, face;
1005
1006     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1007     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1008     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1009     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1010
1011     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1012             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1013     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1014
1015     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1016     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1017
1018     for (y = 0; y < 128; ++y)
1019     {
1020         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1021         for (x = 0; x < 64; ++x)
1022         {
1023             *ptr++ = 0xffff0000;
1024         }
1025         for (x = 64; x < 128; ++x)
1026         {
1027             *ptr++ = 0xff0000ff;
1028         }
1029     }
1030
1031     hr = IDirect3DSurface9_UnlockRect(surface);
1032     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1033
1034     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1035             D3DPOOL_DEFAULT, &texture, NULL);
1036     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1037
1038     /* Create cube faces */
1039     for (face = 0; face < 6; ++face)
1040     {
1041         IDirect3DSurface9 *face_surface = NULL;
1042
1043         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1044         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1045
1046         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1047         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1048
1049         IDirect3DSurface9_Release(face_surface);
1050     }
1051
1052     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1053     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1054
1055     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1056     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1057     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1058     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1059     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1060     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1061
1062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1063     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1064
1065     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1066     {
1067         DWORD color;
1068
1069         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1070         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1071         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1072         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1073
1074         hr = IDirect3DDevice9_BeginScene(device);
1075         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1076
1077         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1078         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1079
1080         hr = IDirect3DDevice9_EndScene(device);
1081         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1082
1083         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1084         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1085
1086         /* Due to the nature of this test, we sample essentially at the edge
1087          * between two faces. Because of this it's undefined from which face
1088          * the driver will sample. Fortunately that's not important for this
1089          * test, since all we care about is that it doesn't sample from the
1090          * other side of the surface or from the border. */
1091         color = getPixelColor(device, 320, 240);
1092         ok(color == 0x00ff0000 || color == 0x000000ff,
1093                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1094                 color, address_modes[x].name);
1095
1096         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1097         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1098     }
1099
1100     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1101     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1102
1103     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1104     IDirect3DCubeTexture9_Release(texture);
1105     IDirect3DSurface9_Release(surface);
1106 }
1107
1108 static void offscreen_test(IDirect3DDevice9 *device)
1109 {
1110     HRESULT hr;
1111     IDirect3DTexture9 *offscreenTexture = NULL;
1112     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1113     DWORD color;
1114
1115     static const float quad[][5] = {
1116         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1117         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1118         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1119         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1120     };
1121
1122     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1123     ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1124
1125     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1126     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1127     if(!offscreenTexture) {
1128         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1129         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1130         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1131         if(!offscreenTexture) {
1132             skip("Cannot create an offscreen render target\n");
1133             goto out;
1134         }
1135     }
1136
1137     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1138     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1139     if(!backbuffer) {
1140         goto out;
1141     }
1142
1143     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1144     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1145     if(!offscreen) {
1146         goto out;
1147     }
1148
1149     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1150     ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1151
1152     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1153     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1154     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1155     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1156     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1157     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1158     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1159     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1160     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1161     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1162
1163     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1164         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1165         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1166         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1167         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1168
1169         /* Draw without textures - Should result in a white quad */
1170         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1171         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1172
1173         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1174         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1175         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1176         ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1177
1178         /* This time with the texture */
1179         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1180         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1181
1182         IDirect3DDevice9_EndScene(device);
1183     }
1184
1185     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1186
1187     /* Center quad - should be white */
1188     color = getPixelColor(device, 320, 240);
1189     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1190     /* Some quad in the cleared part of the texture */
1191     color = getPixelColor(device, 170, 240);
1192     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1193     /* Part of the originally cleared back buffer */
1194     color = getPixelColor(device, 10, 10);
1195     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1196     if(0) {
1197         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1198          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1199          * the offscreen rendering mode this test would succeed or fail
1200          */
1201         color = getPixelColor(device, 10, 470);
1202         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1203     }
1204
1205 out:
1206     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1207
1208     /* restore things */
1209     if(backbuffer) {
1210         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1211         IDirect3DSurface9_Release(backbuffer);
1212     }
1213     if(offscreenTexture) {
1214         IDirect3DTexture9_Release(offscreenTexture);
1215     }
1216     if(offscreen) {
1217         IDirect3DSurface9_Release(offscreen);
1218     }
1219 }
1220
1221 /* This test tests fog in combination with shaders.
1222  * What's tested: linear fog (vertex and table) with pixel shader
1223  *                linear table fog with non foggy vertex shader
1224  *                vertex fog with foggy vertex shader
1225  * What's not tested: non linear fog with shader
1226  *                    table fog with foggy vertex shader
1227  */
1228 static void fog_with_shader_test(IDirect3DDevice9 *device)
1229 {
1230     HRESULT hr;
1231     DWORD color;
1232     union {
1233         float f;
1234         DWORD i;
1235     } start, end;
1236     unsigned int i, j;
1237
1238     /* basic vertex shader without fog computation ("non foggy") */
1239     static const DWORD vertex_shader_code1[] = {
1240         0xfffe0101,                                                             /* vs_1_1                       */
1241         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1242         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1243         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1244         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1245         0x0000ffff
1246     };
1247     /* basic vertex shader with reversed fog computation ("foggy") */
1248     static const DWORD vertex_shader_code2[] = {
1249         0xfffe0101,                                                             /* vs_1_1                        */
1250         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1251         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1252         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1253         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1254         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1255         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1256         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1257         0x0000ffff
1258     };
1259     /* basic pixel shader */
1260     static const DWORD pixel_shader_code[] = {
1261         0xffff0101,                                                             /* ps_1_1     */
1262         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1263         0x0000ffff
1264     };
1265
1266     static struct vertex quad[] = {
1267         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1268         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1269         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1270         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1271     };
1272
1273     static const D3DVERTEXELEMENT9 decl_elements[] = {
1274         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1275         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1276         D3DDECL_END()
1277     };
1278
1279     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1280     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1281     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1282
1283     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1284     static const struct test_data_t {
1285         int vshader;
1286         int pshader;
1287         D3DFOGMODE vfog;
1288         D3DFOGMODE tfog;
1289         unsigned int color[11];
1290     } test_data[] = {
1291         /* only pixel shader: */
1292         {0, 1, 0, 3,
1293         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1294         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1295         {0, 1, 1, 3,
1296         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1297         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1298         {0, 1, 2, 3,
1299         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1300         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1301         {0, 1, 3, 0,
1302         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1303         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1304         {0, 1, 3, 3,
1305         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1306         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1307
1308         /* vertex shader */
1309         {1, 0, 0, 0,
1310         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1311          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1312         {1, 0, 0, 3,
1313         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1314         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1315         {1, 0, 1, 3,
1316         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1317         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1318
1319         {1, 0, 2, 3,
1320         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1321         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1322         {1, 0, 3, 3,
1323         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1324         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1325
1326         /* vertex shader and pixel shader */
1327         {1, 1, 0, 3,
1328         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1329         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1330         {1, 1, 1, 3,
1331         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1332         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1333         {1, 1, 2, 3,
1334         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1335         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1336
1337         {1, 1, 3, 3,
1338         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1339         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1340
1341
1342 #if 0  /* FIXME: these fail on GeForce 8500 */
1343         /* foggy vertex shader */
1344         {2, 0, 0, 0,
1345         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1346          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1347         {2, 0, 1, 0,
1348         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1349          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1350         {2, 0, 2, 0,
1351         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1352          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1353         {2, 0, 3, 0,
1354         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1355          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1356 #endif
1357
1358         /* foggy vertex shader and pixel shader */
1359         {2, 1, 0, 0,
1360         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1361          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1362         {2, 1, 1, 0,
1363         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1364          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1365         {2, 1, 2, 0,
1366         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1367          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1368         {2, 1, 3, 0,
1369         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1370          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1371
1372     };
1373
1374     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1375     start.f=0.1f;
1376     end.f=0.9f;
1377
1378     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1379     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1380     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1381     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1382     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1383     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1384     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1385     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1386
1387     /* Setup initial states: No lighting, fog on, fog color */
1388     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1389     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1390     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1391     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1392     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1393     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1394     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1395     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1396
1397     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1398     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1399     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1400     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1401
1402     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1403     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1404     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1405     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1406     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1407
1408     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1409     {
1410         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1411         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1412         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1413         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1414         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1415         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1416         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1417         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1418
1419         for(j=0; j < 11; j++)
1420         {
1421             /* Don't use the whole zrange to prevent rounding errors */
1422             quad[0].z = 0.001f + (float)j / 10.02f;
1423             quad[1].z = 0.001f + (float)j / 10.02f;
1424             quad[2].z = 0.001f + (float)j / 10.02f;
1425             quad[3].z = 0.001f + (float)j / 10.02f;
1426
1427             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1428             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1429
1430             hr = IDirect3DDevice9_BeginScene(device);
1431             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1432
1433             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1434             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1435
1436             hr = IDirect3DDevice9_EndScene(device);
1437             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1438
1439             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1440
1441             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1442             color = getPixelColor(device, 128, 240);
1443             ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1444                     && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1445                     && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1446                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1447                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1448         }
1449     }
1450
1451     /* reset states */
1452     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1453     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1454     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1455     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1456     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1457     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1458     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1459     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1460
1461     IDirect3DVertexShader9_Release(vertex_shader[1]);
1462     IDirect3DVertexShader9_Release(vertex_shader[2]);
1463     IDirect3DPixelShader9_Release(pixel_shader[1]);
1464     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1465 }
1466
1467 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1468     unsigned int i, x, y;
1469     HRESULT hr;
1470     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1471     D3DLOCKED_RECT locked_rect;
1472
1473     /* Generate the textures */
1474     for(i=0; i<2; i++)
1475     {
1476         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1477                                             D3DPOOL_MANAGED, &texture[i], NULL);
1478         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1479
1480         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1481         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1482         for (y = 0; y < 128; ++y)
1483         {
1484             if(i)
1485             { /* Set up black texture with 2x2 texel white spot in the middle */
1486                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1487                 for (x = 0; x < 128; ++x)
1488                 {
1489                     if(y>62 && y<66 && x>62 && x<66)
1490                         *ptr++ = 0xffffffff;
1491                     else
1492                         *ptr++ = 0xff000000;
1493                 }
1494             }
1495             else
1496             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1497                * (if multiplied with bumpenvmat)
1498               */
1499                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1500                 for (x = 0; x < 128; ++x)
1501                 {
1502                     if(abs(x-64)>abs(y-64))
1503                     {
1504                         if(x < 64)
1505                             *ptr++ = 0xc000;
1506                         else
1507                             *ptr++ = 0x4000;
1508                     }
1509                     else
1510                     {
1511                         if(y < 64)
1512                             *ptr++ = 0x0040;
1513                         else
1514                             *ptr++ = 0x00c0;
1515                     }
1516                 }
1517             }
1518         }
1519         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1520         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1521
1522         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1523         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1524
1525         /* Disable texture filtering */
1526         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1527         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1528         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1529         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1530
1531         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1532         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1533         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1534         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1535     }
1536 }
1537
1538 /* test the behavior of the texbem instruction
1539  * with normal 2D and projective 2D textures
1540  */
1541 static void texbem_test(IDirect3DDevice9 *device)
1542 {
1543     HRESULT hr;
1544     DWORD color;
1545     int i;
1546
1547     static const DWORD pixel_shader_code[] = {
1548         0xffff0101,                         /* ps_1_1*/
1549         0x00000042, 0xb00f0000,             /* tex t0*/
1550         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1551         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1552         0x0000ffff
1553     };
1554     static const DWORD double_texbem_code[] =  {
1555         0xffff0103,                                         /* ps_1_3           */
1556         0x00000042, 0xb00f0000,                             /* tex t0           */
1557         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1558         0x00000042, 0xb00f0002,                             /* tex t2           */
1559         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1560         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1561         0x0000ffff                                          /* end              */
1562     };
1563
1564
1565     static const float quad[][7] = {
1566         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1567         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1568         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1569         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1570     };
1571     static const float quad_proj[][9] = {
1572         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1573         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1574         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1575         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1576     };
1577
1578     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1579         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1580         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1581         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1582         D3DDECL_END()
1583     },{
1584         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1585         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1586         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1587         D3DDECL_END()
1588     } };
1589
1590     /* use asymmetric matrix to test loading */
1591     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1592
1593     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1594     IDirect3DPixelShader9       *pixel_shader       = NULL;
1595     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1596     D3DLOCKED_RECT locked_rect;
1597
1598     generate_bumpmap_textures(device);
1599
1600     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1601     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1602     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1603     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1604     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1605
1606     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1607     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1608
1609     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1610     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1611
1612     for(i=0; i<2; i++)
1613     {
1614         if(i)
1615         {
1616             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1617             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1618         }
1619
1620         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1621         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1622         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1623         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1624
1625         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1626         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1627         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1628         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1629
1630         hr = IDirect3DDevice9_BeginScene(device);
1631         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1632
1633         if(!i)
1634             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1635         else
1636             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1637         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1638
1639         hr = IDirect3DDevice9_EndScene(device);
1640         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1641
1642         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1643         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1644
1645         color = getPixelColor(device, 320-32, 240);
1646         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1647         color = getPixelColor(device, 320+32, 240);
1648         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1649         color = getPixelColor(device, 320, 240-32);
1650         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1651         color = getPixelColor(device, 320, 240+32);
1652         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1653
1654         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1655         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1656         IDirect3DPixelShader9_Release(pixel_shader);
1657
1658         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1659         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1660         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1661     }
1662
1663     /* clean up */
1664     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1665     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1666
1667     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1668     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1669
1670     for(i=0; i<2; i++)
1671     {
1672         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1673         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1674         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1675         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1676         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1677         IDirect3DTexture9_Release(texture);
1678     }
1679
1680     /* Test double texbem */
1681     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1682     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1683     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1684     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1685     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1686     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1687     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1688     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1689
1690     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1691     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1692     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1693     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1694
1695     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1696     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1697
1698     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1699     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1700     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1701     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1702     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1703     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1704
1705     {
1706         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1707 #define tex  0x00ff0000
1708 #define tex1 0x0000ff00
1709 #define origin 0x000000ff
1710         static const DWORD pixel_data[] = {
1711             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1712             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1713             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1714             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1715             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1716             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1717             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1718             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1719         };
1720 #undef tex1
1721 #undef tex2
1722 #undef origin
1723
1724         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1725         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1726         for(i = 0; i < 8; i++) {
1727             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1728         }
1729         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1730         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1731     }
1732
1733     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1734     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1735     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1736     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1737     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1738     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1739     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1740     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1741     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1742     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1743     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1744     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1745
1746     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1747     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1748     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1749     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1750     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1751     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1752
1753     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1754     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1755     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1756     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1757     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1758     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1759
1760     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1761     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1762     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1763     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1764     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1765     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1766     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1767     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1768
1769     hr = IDirect3DDevice9_BeginScene(device);
1770     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1771     if(SUCCEEDED(hr)) {
1772         static const float double_quad[] = {
1773             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1774              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1775             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1776              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1777         };
1778
1779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1780         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1781         hr = IDirect3DDevice9_EndScene(device);
1782         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1783     }
1784     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1785     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1786     color = getPixelColor(device, 320, 240);
1787     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1788
1789     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1790     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1791     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1792     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1793     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1794     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1795     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1796     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1797     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1798     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1799
1800     IDirect3DPixelShader9_Release(pixel_shader);
1801     IDirect3DTexture9_Release(texture);
1802     IDirect3DTexture9_Release(texture1);
1803     IDirect3DTexture9_Release(texture2);
1804 }
1805
1806 static void z_range_test(IDirect3DDevice9 *device)
1807 {
1808     const struct vertex quad[] =
1809     {
1810         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1811         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1812         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1813         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1814     };
1815     const struct vertex quad2[] =
1816     {
1817         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1818         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1819         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1820         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1821     };
1822
1823     const struct tvertex quad3[] =
1824     {
1825         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1826         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1827         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1828         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1829     };
1830     const struct tvertex quad4[] =
1831     {
1832         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1833         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1834         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1835         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1836     };
1837     HRESULT hr;
1838     DWORD color;
1839     IDirect3DVertexShader9 *shader;
1840     IDirect3DVertexDeclaration9 *decl;
1841     D3DCAPS9 caps;
1842     const DWORD shader_code[] = {
1843         0xfffe0101,                                     /* vs_1_1           */
1844         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1845         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1846         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1847         0x0000ffff                                      /* end              */
1848     };
1849     static const D3DVERTEXELEMENT9 decl_elements[] = {
1850         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1851         D3DDECL_END()
1852     };
1853     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1854      * then call Present. Then clear the color buffer to make sure it has some defined content
1855      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1856      * by the depth value.
1857      */
1858     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1859     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1860     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1861     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1862
1863     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1864     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1865     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1866     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1867     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1868     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1869     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1870     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1871     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1872     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1873
1874     hr = IDirect3DDevice9_BeginScene(device);
1875     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1876     if(hr == D3D_OK)
1877     {
1878         /* Test the untransformed vertex path */
1879         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1880         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1881         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1882         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1883         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1884         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1885
1886         /* Test the transformed vertex path */
1887         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1888         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1889
1890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1891         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1892         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1893         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1895         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1896
1897         hr = IDirect3DDevice9_EndScene(device);
1898         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1899     }
1900
1901     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1902     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1903
1904     /* Do not test the exact corner pixels, but go pretty close to them */
1905
1906     /* Clipped because z > 1.0 */
1907     color = getPixelColor(device, 28, 238);
1908     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1909     color = getPixelColor(device, 28, 241);
1910     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1911
1912     /* Not clipped, > z buffer clear value(0.75) */
1913     color = getPixelColor(device, 31, 238);
1914     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1915     color = getPixelColor(device, 31, 241);
1916     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1917     color = getPixelColor(device, 100, 238);
1918     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1919     color = getPixelColor(device, 100, 241);
1920     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1921
1922     /* Not clipped, < z buffer clear value */
1923     color = getPixelColor(device, 104, 238);
1924     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1925     color = getPixelColor(device, 104, 241);
1926     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1927     color = getPixelColor(device, 318, 238);
1928     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1929     color = getPixelColor(device, 318, 241);
1930     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1931
1932     /* Clipped because z < 0.0 */
1933     color = getPixelColor(device, 321, 238);
1934     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1935     color = getPixelColor(device, 321, 241);
1936     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1937
1938     /* Test the shader path */
1939     IDirect3DDevice9_GetDeviceCaps(device, &caps);
1940     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1941         skip("Vertex shaders not supported\n");
1942         goto out;
1943     }
1944     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1945     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1946     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1947     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1948
1949     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1950
1951     IDirect3DDevice9_SetVertexDeclaration(device, decl);
1952     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1953     IDirect3DDevice9_SetVertexShader(device, shader);
1954     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1955
1956     hr = IDirect3DDevice9_BeginScene(device);
1957     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1958     if(hr == D3D_OK)
1959     {
1960         float colorf[] = {1.0, 0.0, 0.0, 1.0};
1961         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1962         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1963         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1964         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1965         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1966         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1967         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1969         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1970
1971         hr = IDirect3DDevice9_EndScene(device);
1972         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1973     }
1974
1975     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1976     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1977     IDirect3DDevice9_SetVertexShader(device, NULL);
1978     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1979
1980     IDirect3DVertexDeclaration9_Release(decl);
1981     IDirect3DVertexShader9_Release(shader);
1982
1983     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1984     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1985     /* Z < 1.0 */
1986     color = getPixelColor(device, 28, 238);
1987     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1988
1989     /* 1.0 < z < 0.75 */
1990     color = getPixelColor(device, 31, 238);
1991     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1992     color = getPixelColor(device, 100, 238);
1993     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1994
1995     /* 0.75 < z < 0.0 */
1996     color = getPixelColor(device, 104, 238);
1997     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1998     color = getPixelColor(device, 318, 238);
1999     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2000
2001     /* 0.0 < z */
2002     color = getPixelColor(device, 321, 238);
2003     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2004
2005     out:
2006     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2007     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2009     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2010     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2011     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2012 }
2013
2014 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2015 {
2016     D3DSURFACE_DESC desc;
2017     D3DLOCKED_RECT l;
2018     HRESULT hr;
2019     unsigned int x, y;
2020     DWORD *mem;
2021
2022     memset(&desc, 0, sizeof(desc));
2023     memset(&l, 0, sizeof(l));
2024     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2025     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2026     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2027     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2028     if(FAILED(hr)) return;
2029
2030     for(y = 0; y < desc.Height; y++)
2031     {
2032         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2033         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2034         {
2035             mem[x] = color;
2036         }
2037     }
2038     hr = IDirect3DSurface9_UnlockRect(surface);
2039     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2040 }
2041
2042 /* This tests a variety of possible StretchRect() situations */
2043 static void stretchrect_test(IDirect3DDevice9 *device)
2044 {
2045     HRESULT hr;
2046     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2047     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2048     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2049     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2050     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2051     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2052     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2053     IDirect3DSurface9 *orig_rt = NULL;
2054     DWORD color;
2055
2056     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2057     ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2058     if(!orig_rt) {
2059         goto out;
2060     }
2061
2062     /* Create our temporary surfaces in system memory */
2063     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2064     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2065     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2066     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2067
2068     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2069     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2070     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2071     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2072     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2073     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2074     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2075
2076     /* Create render target surfaces */
2077     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2078     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2079     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2080     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2081     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2082     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2083
2084     /* Create render target textures */
2085     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2086     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2087     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2088     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2089     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2090     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2091     if (tex_rt32) {
2092         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2093         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2094     }
2095     if (tex_rt64) {
2096         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2097         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2098     }
2099     if (tex_rt_dest64) {
2100         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2101         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2102     }
2103
2104     /* Create regular textures in D3DPOOL_DEFAULT */
2105     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2106     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2107     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2108     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2109     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2110     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2111     if (tex32) {
2112         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2113         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2114     }
2115     if (tex64) {
2116         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2117         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2118     }
2119     if (tex_dest64) {
2120         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2121         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2122     }
2123
2124     /*********************************************************************
2125      * Tests for when the source parameter is an offscreen plain surface *
2126      *********************************************************************/
2127
2128     /* Fill the offscreen 64x64 surface with green */
2129     if (surf_offscreen64)
2130         fill_surface(surf_offscreen64, 0xff00ff00);
2131
2132     /* offscreenplain ==> offscreenplain, same size */
2133     if(surf_offscreen64 && surf_offscreen_dest64) {
2134         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2135         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2136
2137         if (hr == D3D_OK) {
2138             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2139             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2140         }
2141     }
2142
2143     /* offscreenplain ==> rendertarget texture, same size */
2144     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2145         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2146         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2147
2148         /* We can't lock rendertarget textures, so copy to our temp surface first */
2149         if (hr == D3D_OK) {
2150             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2151             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2152         }
2153
2154         if (hr == D3D_OK) {
2155             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2156             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2157         }
2158     }
2159
2160     /* offscreenplain ==> rendertarget surface, same size */
2161     if(surf_offscreen64 && surf_rt_dest64) {
2162         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2163         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2164
2165         if (hr == D3D_OK) {
2166             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2167             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2168         }
2169     }
2170
2171     /* offscreenplain ==> texture, same size (should fail) */
2172     if(surf_offscreen64 && surf_tex_dest64) {
2173         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2174         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2175     }
2176
2177     /* Fill the smaller offscreen surface with red */
2178     fill_surface(surf_offscreen32, 0xffff0000);
2179
2180     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2181     if(surf_offscreen32 && surf_offscreen64) {
2182         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2183         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2184     }
2185
2186     /* offscreenplain ==> rendertarget texture, scaling */
2187     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2188         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2189         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2190
2191         /* We can't lock rendertarget textures, so copy to our temp surface first */
2192         if (hr == D3D_OK) {
2193             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2194             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2195         }
2196
2197         if (hr == D3D_OK) {
2198             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2199             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2200         }
2201     }
2202
2203     /* offscreenplain ==> rendertarget surface, scaling */
2204     if(surf_offscreen32 && surf_rt_dest64) {
2205         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2206         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2207
2208         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2209         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2210     }
2211
2212     /* offscreenplain ==> texture, scaling (should fail) */
2213     if(surf_offscreen32 && surf_tex_dest64) {
2214         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2215         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2216     }
2217
2218     /************************************************************
2219      * Tests for when the source parameter is a regular texture *
2220      ************************************************************/
2221
2222     /* Fill the surface of the regular texture with blue */
2223     if (surf_tex64 && surf_temp64) {
2224         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2225         fill_surface(surf_temp64, 0xff0000ff);
2226         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2227         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2228     }
2229
2230     /* texture ==> offscreenplain, same size */
2231     if(surf_tex64 && surf_offscreen64) {
2232         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2233         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2234     }
2235
2236     /* texture ==> rendertarget texture, same size */
2237     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2238         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2239         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2240
2241         /* We can't lock rendertarget textures, so copy to our temp surface first */
2242         if (hr == D3D_OK) {
2243             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2244             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2245         }
2246
2247         if (hr == D3D_OK) {
2248             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2249             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2250         }
2251     }
2252
2253     /* texture ==> rendertarget surface, same size */
2254     if(surf_tex64 && surf_rt_dest64) {
2255         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2256         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2257
2258         if (hr == D3D_OK) {
2259             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2260             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2261         }
2262     }
2263
2264     /* texture ==> texture, same size (should fail) */
2265     if(surf_tex64 && surf_tex_dest64) {
2266         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2267         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2268     }
2269
2270     /* Fill the surface of the smaller regular texture with red */
2271     if (surf_tex32 && surf_temp32) {
2272         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2273         fill_surface(surf_temp32, 0xffff0000);
2274         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2275         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2276     }
2277
2278     /* texture ==> offscreenplain, scaling (should fail) */
2279     if(surf_tex32 && surf_offscreen64) {
2280         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2281         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2282     }
2283
2284     /* texture ==> rendertarget texture, scaling */
2285     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2286         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2287         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2288
2289         /* We can't lock rendertarget textures, so copy to our temp surface first */
2290         if (hr == D3D_OK) {
2291             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2292             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2293         }
2294
2295         if (hr == D3D_OK) {
2296             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2297             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2298         }
2299     }
2300
2301     /* texture ==> rendertarget surface, scaling */
2302     if(surf_tex32 && surf_rt_dest64) {
2303         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2304         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2305
2306         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2307         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2308     }
2309
2310     /* texture ==> texture, scaling (should fail) */
2311     if(surf_tex32 && surf_tex_dest64) {
2312         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2313         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2314     }
2315
2316     /*****************************************************************
2317      * Tests for when the source parameter is a rendertarget texture *
2318      *****************************************************************/
2319
2320     /* Fill the surface of the rendertarget texture with white */
2321     if (surf_tex_rt64 && surf_temp64) {
2322         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2323         fill_surface(surf_temp64, 0xffffffff);
2324         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2325         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2326     }
2327
2328     /* rendertarget texture ==> offscreenplain, same size */
2329     if(surf_tex_rt64 && surf_offscreen64) {
2330         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2331         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2332     }
2333
2334     /* rendertarget texture ==> rendertarget texture, same size */
2335     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2336         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2337         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2338
2339         /* We can't lock rendertarget textures, so copy to our temp surface first */
2340         if (hr == D3D_OK) {
2341             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2342             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2343         }
2344
2345         if (hr == D3D_OK) {
2346             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2347             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2348         }
2349     }
2350
2351     /* rendertarget texture ==> rendertarget surface, same size */
2352     if(surf_tex_rt64 && surf_rt_dest64) {
2353         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2354         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2355
2356         if (hr == D3D_OK) {
2357             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2358             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2359         }
2360     }
2361
2362     /* rendertarget texture ==> texture, same size (should fail) */
2363     if(surf_tex_rt64 && surf_tex_dest64) {
2364         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2365         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2366     }
2367
2368     /* Fill the surface of the smaller rendertarget texture with red */
2369     if (surf_tex_rt32 && surf_temp32) {
2370         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2371         fill_surface(surf_temp32, 0xffff0000);
2372         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2373         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2374     }
2375
2376     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2377     if(surf_tex_rt32 && surf_offscreen64) {
2378         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2379         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2380     }
2381
2382     /* rendertarget texture ==> rendertarget texture, scaling */
2383     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2384         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2385         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2386
2387         /* We can't lock rendertarget textures, so copy to our temp surface first */
2388         if (hr == D3D_OK) {
2389             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2390             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2391         }
2392
2393         if (hr == D3D_OK) {
2394             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2395             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2396         }
2397     }
2398
2399     /* rendertarget texture ==> rendertarget surface, scaling */
2400     if(surf_tex_rt32 && surf_rt_dest64) {
2401         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2402         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2403
2404         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2405         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2406     }
2407
2408     /* rendertarget texture ==> texture, scaling (should fail) */
2409     if(surf_tex_rt32 && surf_tex_dest64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2411         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2412     }
2413
2414     /*****************************************************************
2415      * Tests for when the source parameter is a rendertarget surface *
2416      *****************************************************************/
2417
2418     /* Fill the surface of the rendertarget surface with black */
2419     if (surf_rt64)
2420         fill_surface(surf_rt64, 0xff000000);
2421
2422     /* rendertarget texture ==> offscreenplain, same size */
2423     if(surf_rt64 && surf_offscreen64) {
2424         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2425         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2426     }
2427
2428     /* rendertarget surface ==> rendertarget texture, same size */
2429     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2430         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2431         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2432
2433         /* We can't lock rendertarget textures, so copy to our temp surface first */
2434         if (hr == D3D_OK) {
2435             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2436             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2437         }
2438
2439         if (hr == D3D_OK) {
2440             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2441             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2442         }
2443     }
2444
2445     /* rendertarget surface ==> rendertarget surface, same size */
2446     if(surf_rt64 && surf_rt_dest64) {
2447         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2448         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2449
2450         if (hr == D3D_OK) {
2451             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2452             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2453         }
2454     }
2455
2456     /* rendertarget surface ==> texture, same size (should fail) */
2457     if(surf_rt64 && surf_tex_dest64) {
2458         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2459         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2460     }
2461
2462     /* Fill the surface of the smaller rendertarget texture with red */
2463     if (surf_rt32)
2464         fill_surface(surf_rt32, 0xffff0000);
2465
2466     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2467     if(surf_rt32 && surf_offscreen64) {
2468         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2469         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2470     }
2471
2472     /* rendertarget surface ==> rendertarget texture, scaling */
2473     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2474         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2475         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2476
2477         /* We can't lock rendertarget textures, so copy to our temp surface first */
2478         if (hr == D3D_OK) {
2479             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2480             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2481         }
2482
2483         if (hr == D3D_OK) {
2484             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2485             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2486         }
2487     }
2488
2489     /* rendertarget surface ==> rendertarget surface, scaling */
2490     if(surf_rt32 && surf_rt_dest64) {
2491         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2492         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2493
2494         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2495         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2496     }
2497
2498     /* rendertarget surface ==> texture, scaling (should fail) */
2499     if(surf_rt32 && surf_tex_dest64) {
2500         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2501         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2502     }
2503
2504     /* TODO: Test when source and destination RECT parameters are given... */
2505     /* TODO: Test format conversions */
2506
2507
2508 out:
2509     /* Clean up */
2510     if (surf_rt32)
2511         IDirect3DSurface9_Release(surf_rt32);
2512     if (surf_rt64)
2513         IDirect3DSurface9_Release(surf_rt64);
2514     if (surf_rt_dest64)
2515         IDirect3DSurface9_Release(surf_rt_dest64);
2516     if (surf_temp32)
2517         IDirect3DSurface9_Release(surf_temp32);
2518     if (surf_temp64)
2519         IDirect3DSurface9_Release(surf_temp64);
2520     if (surf_offscreen32)
2521         IDirect3DSurface9_Release(surf_offscreen32);
2522     if (surf_offscreen64)
2523         IDirect3DSurface9_Release(surf_offscreen64);
2524     if (surf_offscreen_dest64)
2525         IDirect3DSurface9_Release(surf_offscreen_dest64);
2526
2527     if (tex_rt32) {
2528         if (surf_tex_rt32)
2529             IDirect3DSurface9_Release(surf_tex_rt32);
2530         IDirect3DTexture9_Release(tex_rt32);
2531     }
2532     if (tex_rt64) {
2533         if (surf_tex_rt64)
2534             IDirect3DSurface9_Release(surf_tex_rt64);
2535         IDirect3DTexture9_Release(tex_rt64);
2536     }
2537     if (tex_rt_dest64) {
2538         if (surf_tex_rt_dest64)
2539             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2540         IDirect3DTexture9_Release(tex_rt_dest64);
2541     }
2542     if (tex32) {
2543         if (surf_tex32)
2544             IDirect3DSurface9_Release(surf_tex32);
2545         IDirect3DTexture9_Release(tex32);
2546     }
2547     if (tex64) {
2548         if (surf_tex64)
2549             IDirect3DSurface9_Release(surf_tex64);
2550         IDirect3DTexture9_Release(tex64);
2551     }
2552     if (tex_dest64) {
2553         if (surf_tex_dest64)
2554             IDirect3DSurface9_Release(surf_tex_dest64);
2555         IDirect3DTexture9_Release(tex_dest64);
2556     }
2557
2558     if (orig_rt) {
2559         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2560         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2561         IDirect3DSurface9_Release(orig_rt);
2562     }
2563 }
2564
2565 static void maxmip_test(IDirect3DDevice9 *device)
2566 {
2567     IDirect3DTexture9 *texture = NULL;
2568     IDirect3DSurface9 *surface = NULL;
2569     HRESULT hr;
2570     DWORD color;
2571     const float quads[] = {
2572         -1.0,   -1.0,   0.0,    0.0,    0.0,
2573         -1.0,    0.0,   0.0,    0.0,    1.0,
2574          0.0,   -1.0,   0.0,    1.0,    0.0,
2575          0.0,    0.0,   0.0,    1.0,    1.0,
2576
2577          0.0,   -1.0,   0.0,    0.0,    0.0,
2578          0.0,    0.0,   0.0,    0.0,    1.0,
2579          1.0,   -1.0,   0.0,    1.0,    0.0,
2580          1.0,    0.0,   0.0,    1.0,    1.0,
2581
2582          0.0,    0.0,   0.0,    0.0,    0.0,
2583          0.0,    1.0,   0.0,    0.0,    1.0,
2584          1.0,    0.0,   0.0,    1.0,    0.0,
2585          1.0,    1.0,   0.0,    1.0,    1.0,
2586
2587         -1.0,    0.0,   0.0,    0.0,    0.0,
2588         -1.0,    1.0,   0.0,    0.0,    1.0,
2589          0.0,    0.0,   0.0,    1.0,    0.0,
2590          0.0,    1.0,   0.0,    1.0,    1.0,
2591     };
2592
2593     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2594     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2595
2596     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2597                                         &texture, NULL);
2598     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2599     if(!texture)
2600     {
2601         skip("Failed to create test texture\n");
2602         return;
2603     }
2604
2605     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2606     fill_surface(surface, 0xffff0000);
2607     IDirect3DSurface9_Release(surface);
2608     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2609     fill_surface(surface, 0xff00ff00);
2610     IDirect3DSurface9_Release(surface);
2611     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2612     fill_surface(surface, 0xff0000ff);
2613     IDirect3DSurface9_Release(surface);
2614
2615     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2616     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2617     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2619
2620     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2621     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2622
2623     hr = IDirect3DDevice9_BeginScene(device);
2624     if(SUCCEEDED(hr))
2625     {
2626         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2627         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2628         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2629         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2630
2631         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2632         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2633         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2634         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2635
2636         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2637         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2638         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2639         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2640
2641         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2642         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2643         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2644         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2645         hr = IDirect3DDevice9_EndScene(device);
2646     }
2647
2648     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2649     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2650     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2651     color = getPixelColor(device, 160, 360);
2652     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2653     color = getPixelColor(device, 160, 120);
2654     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2655     color = getPixelColor(device, 480, 120);
2656     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2657     color = getPixelColor(device, 480, 360);
2658     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2659
2660     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2661     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2662
2663     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2664     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2665
2666     hr = IDirect3DDevice9_BeginScene(device);
2667     if(SUCCEEDED(hr))
2668     {
2669         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2670         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2672         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2673
2674         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2675         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2676         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2677         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2678
2679         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2680         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2682         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2683
2684         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2685         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2686         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2687         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2688         hr = IDirect3DDevice9_EndScene(device);
2689     }
2690
2691     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2692     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2693     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2694     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2695
2696     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2697     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2698     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2699      * samples from the highest level in the texture(level 2)
2700      */
2701     color = getPixelColor(device, 160, 360);
2702     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2703     color = getPixelColor(device, 160, 120);
2704     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2705     color = getPixelColor(device, 480, 120);
2706     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2707     color = getPixelColor(device, 480, 360);
2708     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2709
2710     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2711     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2712     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2713     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2714     IDirect3DTexture9_Release(texture);
2715 }
2716
2717 static void release_buffer_test(IDirect3DDevice9 *device)
2718 {
2719     IDirect3DVertexBuffer9 *vb = NULL;
2720     IDirect3DIndexBuffer9 *ib = NULL;
2721     HRESULT hr;
2722     BYTE *data;
2723     long ref;
2724
2725     static const struct vertex quad[] = {
2726         {-1.0,      -1.0,       0.1,        0xffff0000},
2727         {-1.0,       1.0,       0.1,        0xffff0000},
2728         { 1.0,       1.0,       0.1,        0xffff0000},
2729
2730         {-1.0,      -1.0,       0.1,        0xff00ff00},
2731         {-1.0,       1.0,       0.1,        0xff00ff00},
2732         { 1.0,       1.0,       0.1,        0xff00ff00}
2733     };
2734     short indices[] = {3, 4, 5};
2735
2736     /* Index and vertex buffers should always be creatable */
2737     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2738                                               D3DPOOL_MANAGED, &vb, NULL);
2739     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2740     if(!vb) {
2741         skip("Failed to create a vertex buffer\n");
2742         return;
2743     }
2744     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2745     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2746     if(!ib) {
2747         skip("Failed to create an index buffer\n");
2748         return;
2749     }
2750
2751     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2752     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2753     memcpy(data, quad, sizeof(quad));
2754     hr = IDirect3DVertexBuffer9_Unlock(vb);
2755     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2756
2757     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2758     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2759     memcpy(data, indices, sizeof(indices));
2760     hr = IDirect3DIndexBuffer9_Unlock(ib);
2761     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2762
2763     hr = IDirect3DDevice9_SetIndices(device, ib);
2764     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %s\n", DXGetErrorString9(hr));
2765     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2766     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
2767     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2768     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2769
2770     /* Now destroy the bound index buffer and draw again */
2771     ref = IDirect3DIndexBuffer9_Release(ib);
2772     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2773
2774     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2775     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2776
2777     hr = IDirect3DDevice9_BeginScene(device);
2778     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2779     if(SUCCEEDED(hr))
2780     {
2781         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2782          * making assumptions about the indices or vertices
2783          */
2784         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2785         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2786         hr = IDirect3DDevice9_EndScene(device);
2787         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2788     }
2789
2790     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2791     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2792
2793     hr = IDirect3DDevice9_SetIndices(device, NULL);
2794     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2795     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2796     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2797
2798     /* Index buffer was already destroyed as part of the test */
2799     IDirect3DVertexBuffer9_Release(vb);
2800 }
2801
2802 static void float_texture_test(IDirect3DDevice9 *device)
2803 {
2804     IDirect3D9 *d3d = NULL;
2805     HRESULT hr;
2806     IDirect3DTexture9 *texture = NULL;
2807     D3DLOCKED_RECT lr;
2808     float *data;
2809     DWORD color;
2810     float quad[] = {
2811         -1.0,      -1.0,       0.1,     0.0,    0.0,
2812         -1.0,       1.0,       0.1,     0.0,    1.0,
2813          1.0,      -1.0,       0.1,     1.0,    0.0,
2814          1.0,       1.0,       0.1,     1.0,    1.0,
2815     };
2816
2817     memset(&lr, 0, sizeof(lr));
2818     IDirect3DDevice9_GetDirect3D(device, &d3d);
2819     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2820                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2821         skip("D3DFMT_R32F textures not supported\n");
2822         goto out;
2823     }
2824
2825     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2826                                         D3DPOOL_MANAGED, &texture, NULL);
2827     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2828     if(!texture) {
2829         skip("Failed to create R32F texture\n");
2830         goto out;
2831     }
2832
2833     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2834     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2835     data = lr.pBits;
2836     *data = 0.0;
2837     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2838     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2839
2840     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2841     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2842
2843     hr = IDirect3DDevice9_BeginScene(device);
2844     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2845     if(SUCCEEDED(hr))
2846     {
2847         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2848         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2849
2850         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2851         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2852
2853         hr = IDirect3DDevice9_EndScene(device);
2854         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2855     }
2856     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2857     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2858
2859     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2860     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2861
2862     color = getPixelColor(device, 240, 320);
2863     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2864
2865 out:
2866     if(texture) IDirect3DTexture9_Release(texture);
2867     IDirect3D9_Release(d3d);
2868 }
2869
2870 static void g16r16_texture_test(IDirect3DDevice9 *device)
2871 {
2872     IDirect3D9 *d3d = NULL;
2873     HRESULT hr;
2874     IDirect3DTexture9 *texture = NULL;
2875     D3DLOCKED_RECT lr;
2876     DWORD *data;
2877     DWORD color, red, green, blue;
2878     float quad[] = {
2879        -1.0,      -1.0,       0.1,     0.0,    0.0,
2880        -1.0,       1.0,       0.1,     0.0,    1.0,
2881         1.0,      -1.0,       0.1,     1.0,    0.0,
2882         1.0,       1.0,       0.1,     1.0,    1.0,
2883     };
2884
2885     memset(&lr, 0, sizeof(lr));
2886     IDirect3DDevice9_GetDirect3D(device, &d3d);
2887     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2888        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2889            skip("D3DFMT_G16R16 textures not supported\n");
2890            goto out;
2891     }
2892
2893     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2894                                         D3DPOOL_MANAGED, &texture, NULL);
2895     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2896     if(!texture) {
2897         skip("Failed to create D3DFMT_G16R16 texture\n");
2898         goto out;
2899     }
2900
2901     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2902     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2903     data = lr.pBits;
2904     *data = 0x0f00f000;
2905     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2906     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2907
2908     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2909     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2910
2911     hr = IDirect3DDevice9_BeginScene(device);
2912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2913     if(SUCCEEDED(hr))
2914     {
2915         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2916         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2917
2918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2919         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2920
2921         hr = IDirect3DDevice9_EndScene(device);
2922         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2923     }
2924     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2925     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2926
2927     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2928     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2929
2930     color = getPixelColor(device, 240, 320);
2931     red   = (color & 0x00ff0000) >> 16;
2932     green = (color & 0x0000ff00) >>  8;
2933     blue  = (color & 0x000000ff) >>  0;
2934     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2935        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2936
2937 out:
2938     if(texture) IDirect3DTexture9_Release(texture);
2939     IDirect3D9_Release(d3d);
2940 }
2941
2942 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2943 {
2944     HRESULT hr;
2945     IDirect3D9 *d3d;
2946     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2947     D3DCAPS9 caps;
2948     IDirect3DTexture9 *texture = NULL;
2949     IDirect3DVolumeTexture9 *volume = NULL;
2950     unsigned int x, y, z;
2951     D3DLOCKED_RECT lr;
2952     D3DLOCKED_BOX lb;
2953     DWORD color;
2954     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2955     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2956                            0.0, 1.0, 0.0, 0.0,
2957                            0.0, 0.0, 1.0, 0.0,
2958                            0.0, 0.0, 0.0, 1.0};
2959     static const D3DVERTEXELEMENT9 decl_elements[] = {
2960         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2961         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2962         D3DDECL_END()
2963     };
2964     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2965         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2966         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2967         D3DDECL_END()
2968     };
2969     static const D3DVERTEXELEMENT9 decl_elements3[] = {
2970         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2971         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2972         D3DDECL_END()
2973     };
2974     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2975                                                  0x00, 0xff, 0x00, 0x00,
2976                                                  0x00, 0x00, 0x00, 0x00,
2977                                                  0x00, 0x00, 0x00, 0x00};
2978
2979     memset(&lr, 0, sizeof(lr));
2980     memset(&lb, 0, sizeof(lb));
2981     IDirect3DDevice9_GetDirect3D(device, &d3d);
2982     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2983                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2984         fmt = D3DFMT_A16B16G16R16;
2985     }
2986     IDirect3D9_Release(d3d);
2987
2988     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2989     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2990     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
2991     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2992     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
2993     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2994     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
2995     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
2996     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2997     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
2998     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2999     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
3000     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3001     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
3002     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3003     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3004     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3005     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3006     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3007     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3012
3013     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3014     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3015     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3016                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3017     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3018     if(!texture) {
3019         skip("Failed to create the test texture\n");
3020         return;
3021     }
3022
3023     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3024      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3025      * 1.0 in red and green for the x and y coords
3026      */
3027     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3028     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3029     for(y = 0; y < caps.MaxTextureHeight; y++) {
3030         for(x = 0; x < caps.MaxTextureWidth; x++) {
3031             double r_f = (double) y / (double) caps.MaxTextureHeight;
3032             double g_f = (double) x / (double) caps.MaxTextureWidth;
3033             if(fmt == D3DFMT_A16B16G16R16) {
3034                 unsigned short r, g;
3035                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3036                 r = (unsigned short) (r_f * 65536.0);
3037                 g = (unsigned short) (g_f * 65536.0);
3038                 dst[0] = r;
3039                 dst[1] = g;
3040                 dst[2] = 0;
3041                 dst[3] = 65535;
3042             } else {
3043                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3044                 unsigned char r = (unsigned char) (r_f * 255.0);
3045                 unsigned char g = (unsigned char) (g_f * 255.0);
3046                 dst[0] = 0;
3047                 dst[1] = g;
3048                 dst[2] = r;
3049                 dst[3] = 255;
3050             }
3051         }
3052     }
3053     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3054     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3055     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3056     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3057
3058     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3059     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3060     hr = IDirect3DDevice9_BeginScene(device);
3061     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3062     if(SUCCEEDED(hr))
3063     {
3064         float quad1[] = {
3065             -1.0,      -1.0,       0.1,     1.0,    1.0,
3066             -1.0,       0.0,       0.1,     1.0,    1.0,
3067              0.0,      -1.0,       0.1,     1.0,    1.0,
3068              0.0,       0.0,       0.1,     1.0,    1.0,
3069         };
3070         float quad2[] = {
3071             -1.0,       0.0,       0.1,     1.0,    1.0,
3072             -1.0,       1.0,       0.1,     1.0,    1.0,
3073              0.0,       0.0,       0.1,     1.0,    1.0,
3074              0.0,       1.0,       0.1,     1.0,    1.0,
3075         };
3076         float quad3[] = {
3077              0.0,       0.0,       0.1,     0.5,    0.5,
3078              0.0,       1.0,       0.1,     0.5,    0.5,
3079              1.0,       0.0,       0.1,     0.5,    0.5,
3080              1.0,       1.0,       0.1,     0.5,    0.5,
3081         };
3082         float quad4[] = {
3083              320,       480,       0.1,     1.0,    0.0,    1.0,
3084              320,       240,       0.1,     1.0,    0.0,    1.0,
3085              640,       480,       0.1,     1.0,    0.0,    1.0,
3086              640,       240,       0.1,     1.0,    0.0,    1.0,
3087         };
3088         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3089                           0.0, 0.0, 0.0, 0.0,
3090                           0.0, 0.0, 0.0, 0.0,
3091                           0.0, 0.0, 0.0, 0.0};
3092
3093         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3094         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3095         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3096         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3097         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3098
3099         /* What happens with transforms enabled? */
3100         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3101         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3102         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3103         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3104
3105         /* What happens if 4 coords are used, but only 2 given ?*/
3106         mat[8] = 1.0;
3107         mat[13] = 1.0;
3108         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3109         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3110         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3111         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3112         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3113         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3114
3115         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3116          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3117          * due to the coords in the vertices. (turns out red, indeed)
3118          */
3119         memset(mat, 0, sizeof(mat));
3120         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3121         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3122         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3123         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3124         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3125         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3126         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3127         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3128
3129         hr = IDirect3DDevice9_EndScene(device);
3130         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3131     }
3132     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3133     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3134     color = getPixelColor(device, 160, 360);
3135     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3136     color = getPixelColor(device, 160, 120);
3137     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3138     color = getPixelColor(device, 480, 120);
3139     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3140     color = getPixelColor(device, 480, 360);
3141     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3142
3143     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3144     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3145
3146     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3147     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3148     hr = IDirect3DDevice9_BeginScene(device);
3149     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3150     if(SUCCEEDED(hr))
3151     {
3152         float quad1[] = {
3153             -1.0,      -1.0,       0.1,     0.8,    0.2,
3154             -1.0,       0.0,       0.1,     0.8,    0.2,
3155              0.0,      -1.0,       0.1,     0.8,    0.2,
3156              0.0,       0.0,       0.1,     0.8,    0.2,
3157         };
3158         float quad2[] = {
3159             -1.0,       0.0,       0.1,     0.5,    1.0,
3160             -1.0,       1.0,       0.1,     0.5,    1.0,
3161              0.0,       0.0,       0.1,     0.5,    1.0,
3162              0.0,       1.0,       0.1,     0.5,    1.0,
3163         };
3164         float quad3[] = {
3165              0.0,       0.0,       0.1,     0.5,    1.0,
3166              0.0,       1.0,       0.1,     0.5,    1.0,
3167              1.0,       0.0,       0.1,     0.5,    1.0,
3168              1.0,       1.0,       0.1,     0.5,    1.0,
3169         };
3170         float quad4[] = {
3171              0.0,      -1.0,       0.1,     0.8,    0.2,
3172              0.0,       0.0,       0.1,     0.8,    0.2,
3173              1.0,      -1.0,       0.1,     0.8,    0.2,
3174              1.0,       0.0,       0.1,     0.8,    0.2,
3175         };
3176         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3177                           0.0, 0.0, 0.0, 0.0,
3178                           0.0, 1.0, 0.0, 0.0,
3179                           0.0, 0.0, 0.0, 0.0};
3180
3181         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3182          */
3183         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3184         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3185         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3186         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3187
3188         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3189         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3190
3191         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3192          * it behaves like COUNT2 because normal textures require 2 coords
3193          */
3194         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3195         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3196         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3197         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3198
3199         /* Just to be sure, the same as quad2 above */
3200         memset(mat, 0, sizeof(mat));
3201         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3202         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3203         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3204         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3205         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3206         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3207
3208         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3209          * used? And what happens to the first?
3210          */
3211         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3212         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3213         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3214         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3215
3216         hr = IDirect3DDevice9_EndScene(device);
3217         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3218     }
3219     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3220     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3221     color = getPixelColor(device, 160, 360);
3222     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3223     color = getPixelColor(device, 160, 120);
3224     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3225     color = getPixelColor(device, 480, 120);
3226     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3227        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3228     color = getPixelColor(device, 480, 360);
3229     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3230        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3231
3232     IDirect3DTexture9_Release(texture);
3233
3234     /* Test projected textures, without any fancy matrices */
3235     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3236     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3237     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3238     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3239     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3241     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3242     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3243
3244     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3245     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3246     for(x = 0; x < 4; x++) {
3247         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3248     }
3249     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3250     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3251     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3252     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3253
3254     hr = IDirect3DDevice9_BeginScene(device);
3255     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3256     if(SUCCEEDED(hr))
3257     {
3258         const float proj_quads[] = {
3259            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3260             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3261            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3262             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3263            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3264             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3265            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3266             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3267         };
3268
3269         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3270         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3271         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3272         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3273
3274         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3275         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3276         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3277         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3278
3279         hr = IDirect3DDevice9_EndScene(device);
3280         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3281     }
3282
3283     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3285     IDirect3DTexture9_Release(texture);
3286
3287     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3288     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3289     color = getPixelColor(device, 158, 118);
3290     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3291     color = getPixelColor(device, 162, 118);
3292     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3293     color = getPixelColor(device, 158, 122);
3294     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3295     color = getPixelColor(device, 162, 122);
3296     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3297
3298     color = getPixelColor(device, 158, 178);
3299     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3300     color = getPixelColor(device, 162, 178);
3301     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3302     color = getPixelColor(device, 158, 182);
3303     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3304     color = getPixelColor(device, 162, 182);
3305     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3306
3307     color = getPixelColor(device, 318, 118);
3308     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3309     color = getPixelColor(device, 322, 118);
3310     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3311     color = getPixelColor(device, 318, 122);
3312     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3313     color = getPixelColor(device, 322, 122);
3314     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3315
3316     color = getPixelColor(device, 318, 178);
3317     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3318     color = getPixelColor(device, 322, 178);
3319     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3320     color = getPixelColor(device, 318, 182);
3321     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3322     color = getPixelColor(device, 322, 182);
3323     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3324
3325     color = getPixelColor(device, 238, 298);
3326     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3327     color = getPixelColor(device, 242, 298);
3328     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3329     color = getPixelColor(device, 238, 302);
3330     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3331     color = getPixelColor(device, 242, 302);
3332     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3333
3334     color = getPixelColor(device, 238, 388);
3335     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3336     color = getPixelColor(device, 242, 388);
3337     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3338     color = getPixelColor(device, 238, 392);
3339     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3340     color = getPixelColor(device, 242, 392);
3341     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3342
3343     color = getPixelColor(device, 478, 298);
3344     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3345     color = getPixelColor(device, 482, 298);
3346     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3347     color = getPixelColor(device, 478, 302);
3348     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3349     color = getPixelColor(device, 482, 302);
3350     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3351
3352     color = getPixelColor(device, 478, 388);
3353     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3354     color = getPixelColor(device, 482, 388);
3355     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3356     color = getPixelColor(device, 478, 392);
3357     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3358     color = getPixelColor(device, 482, 392);
3359     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3360
3361     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3362     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3363     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3364      * Thus watch out if sampling from texels between 0 and 1.
3365      */
3366     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3367     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3368        "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3369     if(!volume) {
3370         skip("Failed to create a volume texture\n");
3371         goto out;
3372     }
3373
3374     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3375     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3376     for(z = 0; z < 32; z++) {
3377         for(y = 0; y < 32; y++) {
3378             for(x = 0; x < 32; x++) {
3379                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3380                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3381                 float r_f = (float) x / 31.0;
3382                 float g_f = (float) y / 31.0;
3383                 float b_f = (float) z / 31.0;
3384
3385                 if(fmt == D3DFMT_A16B16G16R16) {
3386                     unsigned short *mem_s = mem;
3387                     mem_s[0]  = r_f * 65535.0;
3388                     mem_s[1]  = g_f * 65535.0;
3389                     mem_s[2]  = b_f * 65535.0;
3390                     mem_s[3]  = 65535;
3391                 } else {
3392                     unsigned char *mem_c = mem;
3393                     mem_c[0]  = b_f * 255.0;
3394                     mem_c[1]  = g_f * 255.0;
3395                     mem_c[2]  = r_f * 255.0;
3396                     mem_c[3]  = 255;
3397                 }
3398             }
3399         }
3400     }
3401     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3402     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3403
3404     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3405     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3406
3407     hr = IDirect3DDevice9_BeginScene(device);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3409     if(SUCCEEDED(hr))
3410     {
3411         float quad1[] = {
3412             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3413             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3414              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3415              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3416         };
3417         float quad2[] = {
3418             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3419             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3420              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3421              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3422         };
3423         float quad3[] = {
3424              0.0,       0.0,       0.1,     0.0,    0.0,
3425              0.0,       1.0,       0.1,     0.0,    0.0,
3426              1.0,       0.0,       0.1,     0.0,    0.0,
3427              1.0,       1.0,       0.1,     0.0,    0.0
3428         };
3429         float quad4[] = {
3430              0.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              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3433              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3434         };
3435         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3436                          0.0, 0.0, 1.0, 0.0,
3437                          0.0, 1.0, 0.0, 0.0,
3438                          0.0, 0.0, 0.0, 1.0};
3439         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3440         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3441
3442         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3443          * values
3444          */
3445         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3446         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3447         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3448         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3450         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3451
3452         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3453          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3454          * otherwise the w will be missing(blue).
3455          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3456          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3457          */
3458         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3459         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3460         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3461         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3462
3463         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3464         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3465         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3466         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3467         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3468         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3469         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3470         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3471         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3472
3473         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3474          * disable. ATI extends it up to the amount of values needed for the volume texture
3475          */
3476         memset(mat, 0, sizeof(mat));
3477         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3478         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3479         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3480         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3481         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3482         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3483         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3484         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3485
3486         hr = IDirect3DDevice9_EndScene(device);
3487         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3488     }
3489     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3490     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3491
3492     color = getPixelColor(device, 160, 360);
3493     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3494     color = getPixelColor(device, 160, 120);
3495     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3496        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3497     color = getPixelColor(device, 480, 120);
3498     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3499     color = getPixelColor(device, 480, 360);
3500     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3501
3502     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3503     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3504     hr = IDirect3DDevice9_BeginScene(device);
3505     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3506     if(SUCCEEDED(hr))
3507     {
3508         float quad1[] = {
3509             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3510             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3511              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3512              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3513         };
3514         float quad2[] = {
3515             -1.0,       0.0,       0.1,
3516             -1.0,       1.0,       0.1,
3517              0.0,       0.0,       0.1,
3518              0.0,       1.0,       0.1,
3519         };
3520         float quad3[] = {
3521              0.0,       0.0,       0.1,     1.0,
3522              0.0,       1.0,       0.1,     1.0,
3523              1.0,       0.0,       0.1,     1.0,
3524              1.0,       1.0,       0.1,     1.0
3525         };
3526         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3527                            0.0, 0.0, 0.0, 0.0,
3528                            0.0, 0.0, 0.0, 0.0,
3529                            0.0, 1.0, 0.0, 0.0};
3530         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3531                            1.0, 0.0, 0.0, 0.0,
3532                            0.0, 1.0, 0.0, 0.0,
3533                            0.0, 0.0, 1.0, 0.0};
3534         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3535         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3536
3537         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3538          */
3539         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3540         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3541         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3542         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3543         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3544         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3545
3546         /* None passed */
3547         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3548         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3549         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3550         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3551         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3552         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3553
3554         /* 4 used, 1 passed */
3555         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3556         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3557         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3558         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3559         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3560         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3561
3562         hr = IDirect3DDevice9_EndScene(device);
3563         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3564     }
3565     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3566     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3567     color = getPixelColor(device, 160, 360);
3568     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3569     color = getPixelColor(device, 160, 120);
3570     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3571     color = getPixelColor(device, 480, 120);
3572     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3573     /* Quad4: unused */
3574
3575     IDirect3DVolumeTexture9_Release(volume);
3576
3577     out:
3578     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3579     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3580     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3581     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3582     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3583     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3584     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3585     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3586     IDirect3DVertexDeclaration9_Release(decl);
3587     IDirect3DVertexDeclaration9_Release(decl2);
3588     IDirect3DVertexDeclaration9_Release(decl3);
3589 }
3590
3591 static void texdepth_test(IDirect3DDevice9 *device)
3592 {
3593     IDirect3DPixelShader9 *shader;
3594     HRESULT hr;
3595     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3596     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3597     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3598     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3599     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3600     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3601     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3602     DWORD shader_code[] = {
3603         0xffff0104,                                                                 /* ps_1_4               */
3604         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3605         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3606         0x0000fffd,                                                                 /* phase                */
3607         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3608         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3609         0x0000ffff                                                                  /* end                  */
3610     };
3611     DWORD color;
3612     float vertex[] = {
3613        -1.0,   -1.0,    0.0,
3614         1.0,   -1.0,    1.0,
3615        -1.0,    1.0,    0.0,
3616         1.0,    1.0,    1.0
3617     };
3618
3619     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3621
3622     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3624     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3625     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3627     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3628     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3629     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3630     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3631
3632     /* Fill the depth buffer with a gradient */
3633     hr = IDirect3DDevice9_BeginScene(device);
3634     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3635     if(SUCCEEDED(hr))
3636     {
3637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3638         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3639         hr = IDirect3DDevice9_EndScene(device);
3640         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3641     }
3642
3643     /* Now perform the actual tests. Same geometry, but with the shader */
3644     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3645     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3647     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3648     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3649     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3650
3651     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3652     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3653     hr = IDirect3DDevice9_BeginScene(device);
3654     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3655     if(SUCCEEDED(hr))
3656     {
3657         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3658         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3659
3660         hr = IDirect3DDevice9_EndScene(device);
3661         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3662     }
3663
3664     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3665     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3666     color = getPixelColor(device, 158, 240);
3667     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3668     color = getPixelColor(device, 162, 240);
3669     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3670
3671     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3672
3673     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3674     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3675     hr = IDirect3DDevice9_BeginScene(device);
3676     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3677     if(SUCCEEDED(hr))
3678     {
3679         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3680         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3681
3682         hr = IDirect3DDevice9_EndScene(device);
3683         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3684     }
3685
3686     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3687     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3688     color = getPixelColor(device, 318, 240);
3689     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3690     color = getPixelColor(device, 322, 240);
3691     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3692
3693     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3694
3695     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3696     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3697     hr = IDirect3DDevice9_BeginScene(device);
3698     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3699     if(SUCCEEDED(hr))
3700     {
3701         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3702         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3703
3704         hr = IDirect3DDevice9_EndScene(device);
3705         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3706     }
3707     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3708     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3709
3710     color = getPixelColor(device, 1, 240);
3711     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3712
3713     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3714
3715     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3717     hr = IDirect3DDevice9_BeginScene(device);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3719     if(SUCCEEDED(hr))
3720     {
3721         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3722         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3723
3724         hr = IDirect3DDevice9_EndScene(device);
3725         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3726     }
3727     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3729     color = getPixelColor(device, 318, 240);
3730     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3731     color = getPixelColor(device, 322, 240);
3732     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3733
3734     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3735
3736     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3737     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3738     hr = IDirect3DDevice9_BeginScene(device);
3739     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3740     if(SUCCEEDED(hr))
3741     {
3742         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3743         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3744
3745         hr = IDirect3DDevice9_EndScene(device);
3746         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3747     }
3748     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3749     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3750
3751     color = getPixelColor(device, 1, 240);
3752     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3753
3754     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3755
3756     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3757     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3758     hr = IDirect3DDevice9_BeginScene(device);
3759     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3760     if(SUCCEEDED(hr))
3761     {
3762         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3763         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3764
3765         hr = IDirect3DDevice9_EndScene(device);
3766         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3767     }
3768     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3769     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3770
3771     color = getPixelColor(device, 638, 240);
3772     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3773
3774     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3775
3776     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3777     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3778     hr = IDirect3DDevice9_BeginScene(device);
3779     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3780     if(SUCCEEDED(hr))
3781     {
3782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3783         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3784
3785         hr = IDirect3DDevice9_EndScene(device);
3786         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3787     }
3788     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3789     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3790
3791     color = getPixelColor(device, 638, 240);
3792     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3793
3794     /* Cleanup */
3795     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3796     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3797     IDirect3DPixelShader9_Release(shader);
3798
3799     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3801     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3802     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3803 }
3804
3805 static void texkill_test(IDirect3DDevice9 *device)
3806 {
3807     IDirect3DPixelShader9 *shader;
3808     HRESULT hr;
3809     DWORD color;
3810
3811     const float vertex[] = {
3812     /*                          bottom  top    right    left */
3813         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3814          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3815         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3816          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3817     };
3818
3819     DWORD shader_code_11[] = {
3820     0xffff0101,                                                             /* ps_1_1                     */
3821     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3822     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3823     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3824     0x0000ffff                                                              /* end                        */
3825     };
3826     DWORD shader_code_20[] = {
3827     0xffff0200,                                                             /* ps_2_0                     */
3828     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3829     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3830     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3831     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3832     0x0000ffff                                                              /* end                        */
3833     };
3834
3835     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3836     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3837     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3838     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3839
3840     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3841     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3842     hr = IDirect3DDevice9_BeginScene(device);
3843     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3844     if(SUCCEEDED(hr))
3845     {
3846         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3847         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3848         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3849         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3850         hr = IDirect3DDevice9_EndScene(device);
3851         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3852     }
3853     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3854     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3855     color = getPixelColor(device, 63, 46);
3856     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3857     color = getPixelColor(device, 66, 46);
3858     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3859     color = getPixelColor(device, 63, 49);
3860     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3861     color = getPixelColor(device, 66, 49);
3862     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3863
3864     color = getPixelColor(device, 578, 46);
3865     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3866     color = getPixelColor(device, 575, 46);
3867     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3868     color = getPixelColor(device, 578, 49);
3869     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3870     color = getPixelColor(device, 575, 49);
3871     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3872
3873     color = getPixelColor(device, 63, 430);
3874     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3875     color = getPixelColor(device, 63, 433);
3876     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3877     color = getPixelColor(device, 66, 433);
3878     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3879     color = getPixelColor(device, 66, 430);
3880     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3881
3882     color = getPixelColor(device, 578, 430);
3883     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3884     color = getPixelColor(device, 578, 433);
3885     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3886     color = getPixelColor(device, 575, 433);
3887     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3888     color = getPixelColor(device, 575, 430);
3889     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3890
3891     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3892     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3893     IDirect3DPixelShader9_Release(shader);
3894
3895     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3896     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3897     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3898     if(FAILED(hr)) {
3899         skip("Failed to create 2.0 test shader, most likely not supported\n");
3900         return;
3901     }
3902
3903     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3904     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3905     hr = IDirect3DDevice9_BeginScene(device);
3906     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3907     if(SUCCEEDED(hr))
3908     {
3909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3910         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3911         hr = IDirect3DDevice9_EndScene(device);
3912         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3913     }
3914     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3915
3916     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3917     color = getPixelColor(device, 63, 46);
3918     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3919     color = getPixelColor(device, 66, 46);
3920     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3921     color = getPixelColor(device, 63, 49);
3922     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3923     color = getPixelColor(device, 66, 49);
3924     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3925
3926     color = getPixelColor(device, 578, 46);
3927     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3928     color = getPixelColor(device, 575, 46);
3929     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3930     color = getPixelColor(device, 578, 49);
3931     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3932     color = getPixelColor(device, 575, 49);
3933     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3934
3935     color = getPixelColor(device, 63, 430);
3936     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3937     color = getPixelColor(device, 63, 433);
3938     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3939     color = getPixelColor(device, 66, 433);
3940     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3941     color = getPixelColor(device, 66, 430);
3942     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3943
3944     color = getPixelColor(device, 578, 430);
3945     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3946     color = getPixelColor(device, 578, 433);
3947     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3948     color = getPixelColor(device, 575, 433);
3949     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3950     color = getPixelColor(device, 575, 430);
3951     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3952
3953     /* Cleanup */
3954     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3955     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3956     IDirect3DPixelShader9_Release(shader);
3957 }
3958
3959 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3960 {
3961     IDirect3D9 *d3d9;
3962     HRESULT hr;
3963     IDirect3DTexture9 *texture;
3964     IDirect3DPixelShader9 *shader;
3965     IDirect3DPixelShader9 *shader2;
3966     D3DLOCKED_RECT lr;
3967     DWORD color;
3968     DWORD shader_code[] = {
3969         0xffff0101,                             /* ps_1_1       */
3970         0x00000042, 0xb00f0000,                 /* tex t0       */
3971         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3972         0x0000ffff                              /* end          */
3973     };
3974     DWORD shader_code2[] = {
3975         0xffff0101,                             /* ps_1_1       */
3976         0x00000042, 0xb00f0000,                 /* tex t0       */
3977         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3978         0x0000ffff                              /* end          */
3979     };
3980
3981     float quad[] = {
3982        -1.0,   -1.0,   0.1,     0.5,    0.5,
3983         1.0,   -1.0,   0.1,     0.5,    0.5,
3984        -1.0,    1.0,   0.1,     0.5,    0.5,
3985         1.0,    1.0,   0.1,     0.5,    0.5,
3986     };
3987
3988     memset(&lr, 0, sizeof(lr));
3989     IDirect3DDevice9_GetDirect3D(device, &d3d9);
3990     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3991                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
3992     IDirect3D9_Release(d3d9);
3993     if(FAILED(hr)) {
3994         skip("No D3DFMT_X8L8V8U8 support\n");
3995     };
3996
3997     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3998     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3999
4000     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4001     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4002     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4003     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4004     *((DWORD *) lr.pBits) = 0x11ca3141;
4005     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4006     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4007
4008     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4009     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4010     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4011     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4012
4013     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4014     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4015     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4016     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4017     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4018     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4019
4020     hr = IDirect3DDevice9_BeginScene(device);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4022     if(SUCCEEDED(hr))
4023     {
4024         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4025         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4026
4027         hr = IDirect3DDevice9_EndScene(device);
4028         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4029     }
4030     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4031     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4032     color = getPixelColor(device, 578, 430);
4033     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4034        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4035
4036     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4037     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4038     hr = IDirect3DDevice9_BeginScene(device);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4040     if(SUCCEEDED(hr))
4041     {
4042         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4043         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4044
4045         hr = IDirect3DDevice9_EndScene(device);
4046         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4047     }
4048     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4049     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4050     color = getPixelColor(device, 578, 430);
4051     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4052
4053     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4054     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4055     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4056     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4057     IDirect3DPixelShader9_Release(shader);
4058     IDirect3DPixelShader9_Release(shader2);
4059     IDirect3DTexture9_Release(texture);
4060 }
4061
4062 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4063 {
4064     HRESULT hr;
4065     IDirect3D9 *d3d;
4066     IDirect3DTexture9 *texture = NULL;
4067     IDirect3DSurface9 *surface;
4068     DWORD color;
4069     const RECT r1 = {256, 256, 512, 512};
4070     const RECT r2 = {512, 256, 768, 512};
4071     const RECT r3 = {256, 512, 512, 768};
4072     const RECT r4 = {512, 512, 768, 768};
4073     unsigned int x, y;
4074     D3DLOCKED_RECT lr;
4075     memset(&lr, 0, sizeof(lr));
4076
4077     IDirect3DDevice9_GetDirect3D(device, &d3d);
4078     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4079        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4080         skip("No autogenmipmap support\n");
4081         IDirect3D9_Release(d3d);
4082         return;
4083     }
4084     IDirect3D9_Release(d3d);
4085
4086     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4087     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4088
4089     /* Make the mipmap big, so that a smaller mipmap is used
4090      */
4091     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4092                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4093     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4094
4095     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4096     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4097     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4098     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4099     for(y = 0; y < 1024; y++) {
4100         for(x = 0; x < 1024; x++) {
4101             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4102             POINT pt;
4103
4104             pt.x = x;
4105             pt.y = y;
4106             if(PtInRect(&r1, pt)) {
4107                 *dst = 0xffff0000;
4108             } else if(PtInRect(&r2, pt)) {
4109                 *dst = 0xff00ff00;
4110             } else if(PtInRect(&r3, pt)) {
4111                 *dst = 0xff0000ff;
4112             } else if(PtInRect(&r4, pt)) {
4113                 *dst = 0xff000000;
4114             } else {
4115                 *dst = 0xffffffff;
4116             }
4117         }
4118     }
4119     hr = IDirect3DSurface9_UnlockRect(surface);
4120     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4121     IDirect3DSurface9_Release(surface);
4122
4123     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4124     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4125     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4126     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4127
4128     hr = IDirect3DDevice9_BeginScene(device);
4129     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4130     if(SUCCEEDED(hr)) {
4131         const float quad[] =  {
4132            -0.5,   -0.5,    0.1,    0.0,    0.0,
4133            -0.5,    0.5,    0.1,    0.0,    1.0,
4134             0.5,   -0.5,    0.1,    1.0,    0.0,
4135             0.5,    0.5,    0.1,    1.0,    1.0
4136         };
4137
4138         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4139         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4141         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4142         hr = IDirect3DDevice9_EndScene(device);
4143         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4144     }
4145     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4147     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4149     IDirect3DTexture9_Release(texture);
4150
4151     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4153     color = getPixelColor(device, 200, 200);
4154     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4155     color = getPixelColor(device, 280, 200);
4156     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4157     color = getPixelColor(device, 360, 200);
4158     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4159     color = getPixelColor(device, 440, 200);
4160     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4161     color = getPixelColor(device, 200, 270);
4162     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4163     color = getPixelColor(device, 280, 270);
4164     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4165     color = getPixelColor(device, 360, 270);
4166     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4167     color = getPixelColor(device, 440, 270);
4168     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4169 }
4170
4171 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4172 {
4173     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4174     IDirect3DVertexDeclaration9 *decl;
4175     HRESULT hr;
4176     DWORD color;
4177     DWORD shader_code_11[] =  {
4178         0xfffe0101,                                         /* vs_1_1           */
4179         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4180         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4181         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4182         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4183         0x0000ffff                                          /* end              */
4184     };
4185     DWORD shader_code_11_2[] =  {
4186         0xfffe0101,                                         /* vs_1_1           */
4187         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4188         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4189         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4190         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4191         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4192         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4193         0x0000ffff                                          /* end              */
4194     };
4195     DWORD shader_code_20[] =  {
4196         0xfffe0200,                                         /* vs_2_0           */
4197         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4198         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4199         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4200         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4201         0x0000ffff                                          /* end              */
4202     };
4203     DWORD shader_code_20_2[] =  {
4204         0xfffe0200,                                         /* vs_2_0           */
4205         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4206         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4207         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4208         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4209         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4210         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4211         0x0000ffff                                          /* end              */
4212     };
4213     static const D3DVERTEXELEMENT9 decl_elements[] = {
4214         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4215         D3DDECL_END()
4216     };
4217     float quad1[] = {
4218         -1.0,   -1.0,   0.1,
4219          0.0,   -1.0,   0.1,
4220         -1.0,    0.0,   0.1,
4221          0.0,    0.0,   0.1
4222     };
4223     float quad2[] = {
4224          0.0,   -1.0,   0.1,
4225          1.0,   -1.0,   0.1,
4226          0.0,    0.0,   0.1,
4227          1.0,    0.0,   0.1
4228     };
4229     float quad3[] = {
4230          0.0,    0.0,   0.1,
4231          1.0,    0.0,   0.1,
4232          0.0,    1.0,   0.1,
4233          1.0,    1.0,   0.1
4234     };
4235     float quad4[] = {
4236         -1.0,    0.0,   0.1,
4237          0.0,    0.0,   0.1,
4238         -1.0,    1.0,   0.1,
4239          0.0,    1.0,   0.1
4240     };
4241     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4242     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4243
4244     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4245     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4246
4247     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4248     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4249     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4250     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4251     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4252     if(FAILED(hr)) shader_20 = NULL;
4253     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4254     if(FAILED(hr)) shader_20_2 = NULL;
4255     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4256     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4257
4258     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4259     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4260     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4262     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4263     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4264
4265     hr = IDirect3DDevice9_BeginScene(device);
4266     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4267     if(SUCCEEDED(hr))
4268     {
4269         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4270         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4271         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4272         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4273
4274         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4275         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4276         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4277         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4278
4279         if(shader_20) {
4280             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4281             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4282             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4283             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4284         }
4285
4286         if(shader_20_2) {
4287             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4288             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4289             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4290             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4291         }
4292
4293         hr = IDirect3DDevice9_EndScene(device);
4294         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4295     }
4296     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4297     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4298
4299     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4300     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4301     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4302     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4303
4304     color = getPixelColor(device, 160, 360);
4305     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4306        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4307     color = getPixelColor(device, 480, 360);
4308     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4309        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4310     if(shader_20) {
4311         color = getPixelColor(device, 160, 120);
4312         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4313            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4314     }
4315     if(shader_20_2) {
4316         color = getPixelColor(device, 480, 120);
4317         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4318            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4319     }
4320
4321     IDirect3DVertexDeclaration9_Release(decl);
4322     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4323     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4324     IDirect3DVertexShader9_Release(shader_11_2);
4325     IDirect3DVertexShader9_Release(shader_11);
4326 }
4327
4328 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4329 {
4330     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4331     HRESULT hr;
4332     DWORD color;
4333     DWORD shader_code_11[] =  {
4334         0xffff0101,                                         /* ps_1_1           */
4335         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4336         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4337         0x0000ffff                                          /* end              */
4338     };
4339     DWORD shader_code_12[] =  {
4340         0xffff0102,                                         /* ps_1_2           */
4341         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4342         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4343         0x0000ffff                                          /* end              */
4344     };
4345     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4346      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4347      * During development of this test, 1.3 shaders were verified too
4348      */
4349     DWORD shader_code_14[] =  {
4350         0xffff0104,                                         /* ps_1_4           */
4351         /* Try to make one constant local. It gets clamped too, although the binary contains
4352          * the bigger numbers
4353          */
4354         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4355         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4356         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4357         0x0000ffff                                          /* end              */
4358     };
4359     DWORD shader_code_20[] =  {
4360         0xffff0200,                                         /* ps_2_0           */
4361         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4362         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4363         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4364         0x0000ffff                                          /* end              */
4365     };
4366     float quad1[] = {
4367         -1.0,   -1.0,   0.1,
4368          0.0,   -1.0,   0.1,
4369         -1.0,    0.0,   0.1,
4370          0.0,    0.0,   0.1
4371     };
4372     float quad2[] = {
4373          0.0,   -1.0,   0.1,
4374          1.0,   -1.0,   0.1,
4375          0.0,    0.0,   0.1,
4376          1.0,    0.0,   0.1
4377     };
4378     float quad3[] = {
4379          0.0,    0.0,   0.1,
4380          1.0,    0.0,   0.1,
4381          0.0,    1.0,   0.1,
4382          1.0,    1.0,   0.1
4383     };
4384     float quad4[] = {
4385         -1.0,    0.0,   0.1,
4386          0.0,    0.0,   0.1,
4387         -1.0,    1.0,   0.1,
4388          0.0,    1.0,   0.1
4389     };
4390     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4391     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4392
4393     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4395
4396     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4397     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4398     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4399     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4400     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4401     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4402     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4403     if(FAILED(hr)) shader_20 = NULL;
4404
4405     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4406     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4407     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4408     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4409     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4410     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4411
4412     hr = IDirect3DDevice9_BeginScene(device);
4413     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4414     if(SUCCEEDED(hr))
4415     {
4416         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4417         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4418         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4419         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4420
4421         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4422         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4423         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4424         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4425
4426         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4427         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4428         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4429         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4430
4431         if(shader_20) {
4432             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4433             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4434             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4435             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4436         }
4437
4438         hr = IDirect3DDevice9_EndScene(device);
4439         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4440     }
4441     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4442     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4443
4444     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4445     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4446
4447     color = getPixelColor(device, 160, 360);
4448     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4449        "quad 1 has color %08x, expected 0x00808000\n", color);
4450     color = getPixelColor(device, 480, 360);
4451     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4452        "quad 2 has color %08x, expected 0x00808000\n", color);
4453     color = getPixelColor(device, 480, 120);
4454     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4455        "quad 3 has color %08x, expected 0x00808000\n", color);
4456     if(shader_20) {
4457         color = getPixelColor(device, 160, 120);
4458         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4459            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4460     }
4461
4462     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4463     IDirect3DPixelShader9_Release(shader_14);
4464     IDirect3DPixelShader9_Release(shader_12);
4465     IDirect3DPixelShader9_Release(shader_11);
4466 }
4467
4468 static void dp2add_ps_test(IDirect3DDevice9 *device)
4469 {
4470     IDirect3DPixelShader9 *shader_dp2add = NULL;
4471     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4472     HRESULT hr;
4473     DWORD color;
4474
4475     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4476      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4477      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4478      * r0 first.
4479      * The result here for the r,g,b components should be roughly 0.5:
4480      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4481     static const DWORD shader_code_dp2add[] =  {
4482         0xffff0200,                                                             /* ps_2_0                       */
4483         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4484
4485         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4486         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4487
4488         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4489         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4490         0x0000ffff                                                              /* end                          */
4491     };
4492
4493     /* Test the _sat modifier, too.  Result here should be:
4494      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4495      *      _SAT: ==> 1.0
4496      *   ADD: (1.0 + -0.5) = 0.5
4497      */
4498     static const DWORD shader_code_dp2add_sat[] =  {
4499         0xffff0200,                                                             /* ps_2_0                           */
4500         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4501
4502         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4503         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4504         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4505
4506         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4507         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4508         0x0000ffff                                                              /* end                              */
4509     };
4510
4511     const float quad[] = {
4512         -1.0,   -1.0,   0.1,
4513          1.0,   -1.0,   0.1,
4514         -1.0,    1.0,   0.1,
4515          1.0,    1.0,   0.1
4516     };
4517
4518
4519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4521
4522     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4523     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4524
4525     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4526     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4527
4528     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4529     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4530
4531     if (shader_dp2add) {
4532
4533         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4534         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4535
4536         hr = IDirect3DDevice9_BeginScene(device);
4537         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4538         if(SUCCEEDED(hr))
4539         {
4540             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4541             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4542
4543             hr = IDirect3DDevice9_EndScene(device);
4544             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4545         }
4546         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4547         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4548
4549         color = getPixelColor(device, 360, 240);
4550         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4551
4552         IDirect3DPixelShader9_Release(shader_dp2add);
4553     } else {
4554         skip("dp2add shader creation failed\n");
4555     }
4556
4557     if (shader_dp2add_sat) {
4558
4559         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4560         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4561
4562         hr = IDirect3DDevice9_BeginScene(device);
4563         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4564         if(SUCCEEDED(hr))
4565         {
4566             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4567             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4568
4569             hr = IDirect3DDevice9_EndScene(device);
4570             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4571         }
4572         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4573         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4574
4575         color = getPixelColor(device, 360, 240);
4576         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4577
4578         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4579     } else {
4580         skip("dp2add shader creation failed\n");
4581     }
4582
4583     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4584     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4585 }
4586
4587 static void cnd_test(IDirect3DDevice9 *device)
4588 {
4589     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4590     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4591     HRESULT hr;
4592     DWORD color;
4593     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4594      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4595      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4596      */
4597     DWORD shader_code_11[] =  {
4598         0xffff0101,                                                                 /* ps_1_1               */
4599         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4600         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4601         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4602         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4603         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4604         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4605         0x0000ffff                                                                  /* end                  */
4606     };
4607     DWORD shader_code_12[] =  {
4608         0xffff0102,                                                                 /* ps_1_2               */
4609         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4610         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4611         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4612         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4613         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4614         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4615         0x0000ffff                                                                  /* end                  */
4616     };
4617     DWORD shader_code_13[] =  {
4618         0xffff0103,                                                                 /* ps_1_3               */
4619         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4620         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4621         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4622         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4623         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4624         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4625         0x0000ffff                                                                  /* end                  */
4626     };
4627     DWORD shader_code_14[] =  {
4628         0xffff0104,                                                                 /* ps_1_3               */
4629         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4630         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4631         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4632         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4633         0x0000ffff                                                                  /* end                  */
4634     };
4635
4636     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4637      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4638      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4639      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4640      * native CreatePixelShader returns an error.
4641      *
4642      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4643      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4644      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4645      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4646      */
4647     DWORD shader_code_11_coissue[] =  {
4648         0xffff0101,                                                             /* ps_1_1                   */
4649         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4650         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4651         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4652         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4653         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4654         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4655         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4656         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4657         /* 0x40000000 = D3DSI_COISSUE */
4658         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4659         0x0000ffff                                                              /* end                      */
4660     };
4661     DWORD shader_code_12_coissue[] =  {
4662         0xffff0102,                                                             /* ps_1_2                   */
4663         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4664         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4665         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4666         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4667         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4668         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4669         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4670         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4671         /* 0x40000000 = D3DSI_COISSUE */
4672         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4673         0x0000ffff                                                              /* end                      */
4674     };
4675     DWORD shader_code_13_coissue[] =  {
4676         0xffff0103,                                                             /* ps_1_3                   */
4677         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4678         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4679         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4680         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4681         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4682         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4683         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4684         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4685         /* 0x40000000 = D3DSI_COISSUE */
4686         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4687         0x0000ffff                                                              /* end                      */
4688     };
4689     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4690      * compare against 0.5
4691      */
4692     DWORD shader_code_14_coissue[] =  {
4693         0xffff0104,                                                             /* ps_1_4                   */
4694         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4695         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4696         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4697         /* 0x40000000 = D3DSI_COISSUE */
4698         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4699         0x0000ffff                                                              /* end                      */
4700     };
4701     float quad1[] = {
4702         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4703          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4704         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4705          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4706     };
4707     float quad2[] = {
4708          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4709          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4710          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4711          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4712     };
4713     float quad3[] = {
4714          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4715          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4716          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4717          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4718     };
4719     float quad4[] = {
4720         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4721          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4722         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4723          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4724     };
4725     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4726     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4727     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4728     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4729
4730     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4731     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4732
4733     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4734     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4735     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4736     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4737     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4738     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4739     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4740     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4741     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4742     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4743     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4744     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4745     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4746     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4747     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4748     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4749
4750     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4752     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4754     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4755     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4756
4757     hr = IDirect3DDevice9_BeginScene(device);
4758     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4759     if(SUCCEEDED(hr))
4760     {
4761         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4762         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4763         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4764         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4765
4766         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4767         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4768         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4769         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4770
4771         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4772         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4773         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4774         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4775
4776         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4777         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4778         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4779         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4780
4781         hr = IDirect3DDevice9_EndScene(device);
4782         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4783     }
4784     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4785     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4786
4787     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4788     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4789
4790     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4791     color = getPixelColor(device, 158, 118);
4792     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4793     color = getPixelColor(device, 162, 118);
4794     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4795     color = getPixelColor(device, 158, 122);
4796     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4797     color = getPixelColor(device, 162, 122);
4798     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4799
4800     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4801     color = getPixelColor(device, 158, 358);
4802     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4803     color = getPixelColor(device, 162, 358);
4804     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4805         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4806     color = getPixelColor(device, 158, 362);
4807     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4808     color = getPixelColor(device, 162, 362);
4809     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4810         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4811
4812     /* 1.2 shader */
4813     color = getPixelColor(device, 478, 358);
4814     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4815     color = getPixelColor(device, 482, 358);
4816     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4817         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4818     color = getPixelColor(device, 478, 362);
4819     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4820     color = getPixelColor(device, 482, 362);
4821     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4822         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4823
4824     /* 1.3 shader */
4825     color = getPixelColor(device, 478, 118);
4826     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4827     color = getPixelColor(device, 482, 118);
4828     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4829         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4830     color = getPixelColor(device, 478, 122);
4831     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4832     color = getPixelColor(device, 482, 122);
4833     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4834         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4835
4836     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4837     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4838     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4839     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4840     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4841     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4842
4843     hr = IDirect3DDevice9_BeginScene(device);
4844     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4845     if(SUCCEEDED(hr))
4846     {
4847         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4848         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4849         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4850         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4851
4852         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4853         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4854         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4855         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4856
4857         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4858         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4859         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4860         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4861
4862         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4863         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4864         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4865         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4866
4867         hr = IDirect3DDevice9_EndScene(device);
4868         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4869     }
4870     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4871     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4872
4873     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4874      * that we swapped the values in c1 and c2 to make the other tests return some color
4875      */
4876     color = getPixelColor(device, 158, 118);
4877     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4878     color = getPixelColor(device, 162, 118);
4879     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4880     color = getPixelColor(device, 158, 122);
4881     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4882     color = getPixelColor(device, 162, 122);
4883     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4884
4885     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4886     color = getPixelColor(device, 158, 358);
4887     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4888         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4889     color = getPixelColor(device, 162, 358);
4890     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4891         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4892     color = getPixelColor(device, 158, 362);
4893     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4894         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4895     color = getPixelColor(device, 162, 362);
4896     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4897         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4898
4899     /* 1.2 shader */
4900     color = getPixelColor(device, 478, 358);
4901     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4902         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4903     color = getPixelColor(device, 482, 358);
4904     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4905         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4906     color = getPixelColor(device, 478, 362);
4907     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4908         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4909     color = getPixelColor(device, 482, 362);
4910     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4911         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4912
4913     /* 1.3 shader */
4914     color = getPixelColor(device, 478, 118);
4915     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4916         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4917     color = getPixelColor(device, 482, 118);
4918     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4919         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4920     color = getPixelColor(device, 478, 122);
4921     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4922         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4923     color = getPixelColor(device, 482, 122);
4924     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4925         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4926
4927     IDirect3DPixelShader9_Release(shader_14_coissue);
4928     IDirect3DPixelShader9_Release(shader_13_coissue);
4929     IDirect3DPixelShader9_Release(shader_12_coissue);
4930     IDirect3DPixelShader9_Release(shader_11_coissue);
4931     IDirect3DPixelShader9_Release(shader_14);
4932     IDirect3DPixelShader9_Release(shader_13);
4933     IDirect3DPixelShader9_Release(shader_12);
4934     IDirect3DPixelShader9_Release(shader_11);
4935 }
4936
4937 static void nested_loop_test(IDirect3DDevice9 *device) {
4938     const DWORD shader_code[] = {
4939         0xffff0300,                                                             /* ps_3_0               */
4940         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4941         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4942         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4943         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4944         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4945         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4946         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4947         0x0000001d,                                                             /* endloop              */
4948         0x0000001d,                                                             /* endloop              */
4949         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4950         0x0000ffff                                                              /* end                  */
4951     };
4952     IDirect3DPixelShader9 *shader;
4953     HRESULT hr;
4954     DWORD color;
4955     const float quad[] = {
4956         -1.0,   -1.0,   0.1,
4957          1.0,   -1.0,   0.1,
4958         -1.0,    1.0,   0.1,
4959          1.0,    1.0,   0.1
4960     };
4961
4962     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4963     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4964     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4965     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4966     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4967     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4968     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4969     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4970
4971     hr = IDirect3DDevice9_BeginScene(device);
4972     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4973     if(SUCCEEDED(hr))
4974     {
4975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4976         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4977         hr = IDirect3DDevice9_EndScene(device);
4978         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4979     }
4980     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4981     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4982
4983     color = getPixelColor(device, 360, 240);
4984     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4985        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4986
4987     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4988     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4989     IDirect3DPixelShader9_Release(shader);
4990 }
4991
4992 struct varying_test_struct
4993 {
4994     const DWORD             *shader_code;
4995     IDirect3DPixelShader9   *shader;
4996     DWORD                   color, color_rhw;
4997     const char              *name;
4998     BOOL                    todo, todo_rhw;
4999 };
5000
5001 struct hugeVertex
5002 {
5003     float pos_x,        pos_y,      pos_z,      rhw;
5004     float weight_1,     weight_2,   weight_3,   weight_4;
5005     float index_1,      index_2,    index_3,    index_4;
5006     float normal_1,     normal_2,   normal_3,   normal_4;
5007     float fog_1,        fog_2,      fog_3,      fog_4;
5008     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5009     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5010     float binormal_1,   binormal_2, binormal_3, binormal_4;
5011     float depth_1,      depth_2,    depth_3,    depth_4;
5012     DWORD diffuse, specular;
5013 };
5014
5015 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5016     /* dcl_position: fails to compile */
5017     const DWORD blendweight_code[] = {
5018         0xffff0300,                             /* ps_3_0                   */
5019         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5020         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5021         0x0000ffff                              /* end                      */
5022     };
5023     const DWORD blendindices_code[] = {
5024         0xffff0300,                             /* ps_3_0                   */
5025         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5026         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5027         0x0000ffff                              /* end                      */
5028     };
5029     const DWORD normal_code[] = {
5030         0xffff0300,                             /* ps_3_0                   */
5031         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5032         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5033         0x0000ffff                              /* end                      */
5034     };
5035     /* psize: fails? */
5036     const DWORD texcoord0_code[] = {
5037         0xffff0300,                             /* ps_3_0                   */
5038         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5039         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5040         0x0000ffff                              /* end                      */
5041     };
5042     const DWORD tangent_code[] = {
5043         0xffff0300,                             /* ps_3_0                   */
5044         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5045         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5046         0x0000ffff                              /* end                      */
5047     };
5048     const DWORD binormal_code[] = {
5049         0xffff0300,                             /* ps_3_0                   */
5050         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5051         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5052         0x0000ffff                              /* end                      */
5053     };
5054     /* tessfactor: fails */
5055     /* positiont: fails */
5056     const DWORD color_code[] = {
5057         0xffff0300,                             /* ps_3_0                   */
5058         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5059         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5060         0x0000ffff                              /* end                      */
5061     };
5062     const DWORD fog_code[] = {
5063         0xffff0300,                             /* ps_3_0                   */
5064         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5065         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5066         0x0000ffff                              /* end                      */
5067     };
5068     const DWORD depth_code[] = {
5069         0xffff0300,                             /* ps_3_0                   */
5070         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5071         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5072         0x0000ffff                              /* end                      */
5073     };
5074     const DWORD specular_code[] = {
5075         0xffff0300,                             /* ps_3_0                   */
5076         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5077         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5078         0x0000ffff                              /* end                      */
5079     };
5080     /* sample: fails */
5081
5082     struct varying_test_struct tests[] = {
5083        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5084        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5085        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5086        /* Why does dx not forward the texcoord? */
5087        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5088        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5089        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5090        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5091        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5092        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5093        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5094     };
5095     /* Declare a monster vertex type :-) */
5096     static const D3DVERTEXELEMENT9 decl_elements[] = {
5097         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5098         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5099         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5100         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5101         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5102         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5103         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5104         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5105         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5106         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5107         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5108         D3DDECL_END()
5109     };
5110     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5111         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5112         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5113         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5114         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5115         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5116         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5117         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5118         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5119         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5120         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5121         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5122         D3DDECL_END()
5123     };
5124     struct hugeVertex data[4] = {
5125         {
5126             -1.0,   -1.0,   0.1,    1.0,
5127              0.1,    0.1,   0.1,    0.1,
5128              0.2,    0.2,   0.2,    0.2,
5129              0.3,    0.3,   0.3,    0.3,
5130              0.4,    0.4,   0.4,    0.4,
5131              0.50,   0.55,  0.55,   0.55,
5132              0.6,    0.6,   0.6,    0.7,
5133              0.7,    0.7,   0.7,    0.6,
5134              0.8,    0.8,   0.8,    0.8,
5135              0xe6e6e6e6, /* 0.9 * 256 */
5136              0x224488ff  /* Nothing special */
5137         },
5138         {
5139              1.0,   -1.0,   0.1,    1.0,
5140              0.1,    0.1,   0.1,    0.1,
5141              0.2,    0.2,   0.2,    0.2,
5142              0.3,    0.3,   0.3,    0.3,
5143              0.4,    0.4,   0.4,    0.4,
5144              0.50,   0.55,  0.55,   0.55,
5145              0.6,    0.6,   0.6,    0.7,
5146              0.7,    0.7,   0.7,    0.6,
5147              0.8,    0.8,   0.8,    0.8,
5148              0xe6e6e6e6, /* 0.9 * 256 */
5149              0x224488ff /* Nothing special */
5150         },
5151         {
5152             -1.0,    1.0,   0.1,    1.0,
5153              0.1,    0.1,   0.1,    0.1,
5154              0.2,    0.2,   0.2,    0.2,
5155              0.3,    0.3,   0.3,    0.3,
5156              0.4,    0.4,   0.4,    0.4,
5157              0.50,   0.55,  0.55,   0.55,
5158              0.6,    0.6,   0.6,    0.7,
5159              0.7,    0.7,   0.7,    0.6,
5160              0.8,    0.8,   0.8,    0.8,
5161              0xe6e6e6e6, /* 0.9 * 256 */
5162              0x224488ff /* Nothing special */
5163         },
5164         {
5165              1.0,    1.0,   0.1,    1.0,
5166              0.1,    0.1,   0.1,    0.1,
5167              0.2,    0.2,   0.2,    0.2,
5168              0.3,    0.3,   0.3,    0.3,
5169              0.4,    0.4,   0.4,    0.4,
5170              0.50,   0.55,  0.55,   0.55,
5171              0.6,    0.6,   0.6,    0.7,
5172              0.7,    0.7,   0.7,    0.6,
5173              0.8,    0.8,   0.8,    0.8,
5174              0xe6e6e6e6, /* 0.9 * 256 */
5175              0x224488ff /* Nothing special */
5176         },
5177     };
5178     struct hugeVertex data2[4];
5179     IDirect3DVertexDeclaration9 *decl;
5180     IDirect3DVertexDeclaration9 *decl2;
5181     HRESULT hr;
5182     unsigned int i;
5183     DWORD color, r, g, b, r_e, g_e, b_e;
5184     BOOL drawok;
5185
5186     memcpy(data2, data, sizeof(data2));
5187     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5188     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5189     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5190     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5191
5192     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5193     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5194     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5195     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5196     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5197     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5198
5199     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5200     {
5201         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5202         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5203            tests[i].name, DXGetErrorString9(hr));
5204     }
5205
5206     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5207     {
5208         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5209         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5210
5211         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5212         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5213
5214         hr = IDirect3DDevice9_BeginScene(device);
5215         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5216         drawok = FALSE;
5217         if(SUCCEEDED(hr))
5218         {
5219             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5220             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5221             drawok = SUCCEEDED(hr);
5222             hr = IDirect3DDevice9_EndScene(device);
5223             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5224         }
5225         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5226         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5227
5228         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5229          * the failure and do not check the color if it failed
5230          */
5231         if(!drawok) {
5232             continue;
5233         }
5234
5235         color = getPixelColor(device, 360, 240);
5236         r = color & 0x00ff0000 >> 16;
5237         g = color & 0x0000ff00 >>  8;
5238         b = color & 0x000000ff;
5239         r_e = tests[i].color & 0x00ff0000 >> 16;
5240         g_e = tests[i].color & 0x0000ff00 >>  8;
5241         b_e = tests[i].color & 0x000000ff;
5242
5243         if(tests[i].todo) {
5244             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5245                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5246                          tests[i].name, color, tests[i].color);
5247         } else {
5248             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5249                "Test %s returned color 0x%08x, expected 0x%08x\n",
5250                tests[i].name, color, tests[i].color);
5251         }
5252     }
5253
5254     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5255     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5256     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5257     {
5258         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5259         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5260
5261         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5262         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5263
5264         hr = IDirect3DDevice9_BeginScene(device);
5265         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5266         if(SUCCEEDED(hr))
5267         {
5268             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5269             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5270             hr = IDirect3DDevice9_EndScene(device);
5271             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5272         }
5273         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5274         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5275
5276         color = getPixelColor(device, 360, 240);
5277         r = color & 0x00ff0000 >> 16;
5278         g = color & 0x0000ff00 >>  8;
5279         b = color & 0x000000ff;
5280         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5281         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5282         b_e = tests[i].color_rhw & 0x000000ff;
5283
5284         if(tests[i].todo_rhw) {
5285             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5286              * pipeline
5287              */
5288             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5289                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5290                          tests[i].name, color, tests[i].color_rhw);
5291         } else {
5292             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5293                "Test %s returned color 0x%08x, expected 0x%08x\n",
5294                tests[i].name, color, tests[i].color_rhw);
5295         }
5296     }
5297
5298     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5299     {
5300         IDirect3DPixelShader9_Release(tests[i].shader);
5301     }
5302
5303     IDirect3DVertexDeclaration9_Release(decl2);
5304     IDirect3DVertexDeclaration9_Release(decl);
5305 }
5306
5307 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5308     static const DWORD ps_code[] = {
5309     0xffff0300,                                                             /* ps_3_0                       */
5310     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5311     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5312     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5313     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5314     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5315     0x0200001f, 0x80000003, 0x900f0006,
5316     0x0200001f, 0x80000006, 0x900f0007,
5317     0x0200001f, 0x80000001, 0x900f0008,
5318     0x0200001f, 0x8000000c, 0x900f0009,
5319
5320     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5321     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5322     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5323     0x0000001d,                                                             /* endloop                      */
5324     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5325     0x0000ffff                                                              /* end                          */
5326     };
5327     static const DWORD vs_1_code[] = {
5328     0xfffe0101,                                                             /* vs_1_1                       */
5329     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5330     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5331     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5332     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5333     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5334     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5335     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5336     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5337     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5338     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5339     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5340     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5341     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5342     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5343     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5344     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5345     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5346     0x0000ffff
5347     };
5348     DWORD vs_2_code[] = {
5349     0xfffe0200,                                                             /* vs_2_0                       */
5350     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5351     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
5352     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0   */
5353     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0   */
5354     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5355     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5356     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5357     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5358     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5359     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5360     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5361     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5362     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5363     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5364     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5365     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5366     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5367     0x0000ffff                                                              /* end                          */
5368     };
5369     /* TODO: Define normal, tangent, blendweight and depth here */
5370     static const DWORD vs_3_code[] = {
5371     0xfffe0300,                                                             /* vs_3_0                       */
5372     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5373     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5374     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5375     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5376     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5377     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5378     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5379     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5380     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5381     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5382     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5383     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5384     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5385     0x0000ffff                                                              /* end                          */
5386     };
5387     float quad1[] =  {
5388         -1.0,   -1.0,   0.1,
5389          0.0,   -1.0,   0.1,
5390         -1.0,    0.0,   0.1,
5391          0.0,    0.0,   0.1
5392     };
5393     float quad2[] =  {
5394          0.0,   -1.0,   0.1,
5395          1.0,   -1.0,   0.1,
5396          0.0,    0.0,   0.1,
5397          1.0,    0.0,   0.1
5398     };
5399     float quad3[] =  {
5400         -1.0,    0.0,   0.1,
5401          0.0,    0.0,   0.1,
5402         -1.0,    1.0,   0.1,
5403          0.0,    1.0,   0.1
5404     };
5405
5406     HRESULT hr;
5407     DWORD color;
5408     IDirect3DPixelShader9 *pixelshader = NULL;
5409     IDirect3DVertexShader9 *vs_1_shader = NULL;
5410     IDirect3DVertexShader9 *vs_2_shader = NULL;
5411     IDirect3DVertexShader9 *vs_3_shader = NULL;
5412
5413     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5414
5415     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5416     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5417     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5418     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5419     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5420     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5421     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5422     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5423     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5424     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5425     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5426
5427     hr = IDirect3DDevice9_BeginScene(device);
5428     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5429     if(SUCCEEDED(hr))
5430     {
5431         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5432         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5433         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5434         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5435
5436         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5437         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5438         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5439         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5440
5441         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5442         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5443         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5444         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5445
5446         hr = IDirect3DDevice9_EndScene(device);
5447         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5448     }
5449     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5450     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5451
5452     color = getPixelColor(device, 160, 120);
5453     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5454        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5455        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5456        "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5457     color = getPixelColor(device, 160, 360);
5458     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5459        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5460        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5461        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5462     color = getPixelColor(device, 480, 360);
5463     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5464        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5465        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5466        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5467
5468     /* cleanup */
5469     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5470     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5471     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5472     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5473     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5474     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5475     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5476     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5477 }
5478
5479 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5480     static const DWORD vs_code[] = {
5481     0xfffe0300,                                                             /* vs_3_0                       */
5482     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5483     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5484     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5485     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5486     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5487     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5488     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5489     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5490     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5491     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5492     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5493     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5494     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5495
5496     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5497     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5498     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5499     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5500     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5501     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5502     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5503     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5504     0x0000ffff                                                              /* end                          */
5505     };
5506     static const DWORD ps_1_code[] = {
5507     0xffff0104,                                                             /* ps_1_4                       */
5508     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5509     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5510     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5511     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5512     0x0000ffff                                                              /* end                          */
5513     };
5514     static const DWORD ps_2_code[] = {
5515     0xffff0200,                                                             /* ps_2_0                       */
5516     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5517     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5518     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5519
5520     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5521     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5522     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5523     0x0000ffff                                                              /* end                          */
5524     };
5525     static const DWORD ps_3_code[] = {
5526     0xffff0300,                                                             /* ps_3_0                       */
5527     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5528     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5529     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5530
5531     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5532     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5533     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5534     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5535     0x0000ffff                                                              /* end                          */
5536     };
5537
5538     float quad1[] =  {
5539         -1.0,   -1.0,   0.1,
5540          0.0,   -1.0,   0.1,
5541         -1.0,    0.0,   0.1,
5542          0.0,    0.0,   0.1
5543     };
5544     float quad2[] =  {
5545          0.0,   -1.0,   0.1,
5546          1.0,   -1.0,   0.1,
5547          0.0,    0.0,   0.1,
5548          1.0,    0.0,   0.1
5549     };
5550     float quad3[] =  {
5551         -1.0,    0.0,   0.1,
5552          0.0,    0.0,   0.1,
5553         -1.0,    1.0,   0.1,
5554          0.0,    1.0,   0.1
5555     };
5556     float quad4[] =  {
5557          0.0,    0.0,   0.1,
5558          1.0,    0.0,   0.1,
5559          0.0,    1.0,   0.1,
5560          1.0,    1.0,   0.1
5561     };
5562
5563     HRESULT hr;
5564     DWORD color;
5565     IDirect3DVertexShader9 *vertexshader = NULL;
5566     IDirect3DPixelShader9 *ps_1_shader = NULL;
5567     IDirect3DPixelShader9 *ps_2_shader = NULL;
5568     IDirect3DPixelShader9 *ps_3_shader = NULL;
5569     IDirect3DTexture9 *texture = NULL;
5570     D3DLOCKED_RECT lr;
5571     unsigned int x, y;
5572
5573     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5574
5575     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5576     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5577     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5578     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5579     for(y = 0; y < 512; y++) {
5580         for(x = 0; x < 512; x++) {
5581             double r_f = (double) x / (double) 512;
5582             double g_f = (double) y / (double) 512;
5583             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5584             unsigned short r = (unsigned short) (r_f * 65535.0);
5585             unsigned short g = (unsigned short) (g_f * 65535.0);
5586             dst[0] = r;
5587             dst[1] = g;
5588             dst[2] = 0;
5589             dst[3] = 65535;
5590         }
5591     }
5592     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5593     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5594
5595     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5596     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5597     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5598     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5599     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5600     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5601     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5602     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5603     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5604     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5605     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5606
5607     hr = IDirect3DDevice9_BeginScene(device);
5608     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5609     if(SUCCEEDED(hr))
5610     {
5611         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5612         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5613         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5614         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5615
5616         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5617         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5618         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5619         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5620
5621         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5622         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5623         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5624         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5625
5626         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5627         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5628         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5629         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5630         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5631         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5632         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5633         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5635         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5636
5637         hr = IDirect3DDevice9_EndScene(device);
5638         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5639     }
5640     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5641     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5642
5643     color = getPixelColor(device, 160, 120);
5644     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5645        (color & 0x0000ff00) == 0x0000ff00 &&
5646        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5647        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5648     color = getPixelColor(device, 160, 360);
5649     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5650        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5651        (color & 0x000000ff) == 0x00000000,
5652        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5653     color = getPixelColor(device, 480, 360);
5654     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5655        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5656        (color & 0x000000ff) == 0x00000000,
5657        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5658     color = getPixelColor(device, 480, 160);
5659     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5660        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5661        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5662        (color & 0x000000ff) == 0x00000000),
5663        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5664
5665     /* cleanup */
5666     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5667     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5668     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5669     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5670     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5671     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5672     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5673     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5674     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5675     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5676     if(texture) IDirect3DTexture9_Release(texture);
5677 }
5678
5679 void test_compare_instructions(IDirect3DDevice9 *device)
5680 {
5681     DWORD shader_sge_vec_code[] = {
5682         0xfffe0101,                                         /* vs_1_1                   */
5683         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5684         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5685         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5686         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5687         0x0000ffff                                          /* end                      */
5688     };
5689     DWORD shader_slt_vec_code[] = {
5690         0xfffe0101,                                         /* vs_1_1                   */
5691         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5692         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5693         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5694         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5695         0x0000ffff                                          /* end                      */
5696     };
5697     DWORD shader_sge_scalar_code[] = {
5698         0xfffe0101,                                         /* vs_1_1                   */
5699         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5700         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5701         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5702         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5703         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5704         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5705         0x0000ffff                                          /* end                      */
5706     };
5707     DWORD shader_slt_scalar_code[] = {
5708         0xfffe0101,                                         /* vs_1_1                   */
5709         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5710         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5711         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5712         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5713         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5714         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5715         0x0000ffff                                          /* end                      */
5716     };
5717     IDirect3DVertexShader9 *shader_sge_vec;
5718     IDirect3DVertexShader9 *shader_slt_vec;
5719     IDirect3DVertexShader9 *shader_sge_scalar;
5720     IDirect3DVertexShader9 *shader_slt_scalar;
5721     HRESULT hr, color;
5722     float quad1[] =  {
5723         -1.0,   -1.0,   0.1,
5724          0.0,   -1.0,   0.1,
5725         -1.0,    0.0,   0.1,
5726          0.0,    0.0,   0.1
5727     };
5728     float quad2[] =  {
5729          0.0,   -1.0,   0.1,
5730          1.0,   -1.0,   0.1,
5731          0.0,    0.0,   0.1,
5732          1.0,    0.0,   0.1
5733     };
5734     float quad3[] =  {
5735         -1.0,    0.0,   0.1,
5736          0.0,    0.0,   0.1,
5737         -1.0,    1.0,   0.1,
5738          0.0,    1.0,   0.1
5739     };
5740     float quad4[] =  {
5741          0.0,    0.0,   0.1,
5742          1.0,    0.0,   0.1,
5743          0.0,    1.0,   0.1,
5744          1.0,    1.0,   0.1
5745     };
5746     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5747     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5748
5749     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5750
5751     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5752     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5753     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5754     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5755     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5756     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5757     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5758     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5759     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5760     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5761     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5762     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5764     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5765
5766     hr = IDirect3DDevice9_BeginScene(device);
5767     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5768     if(SUCCEEDED(hr))
5769     {
5770         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5771         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5772         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5773         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5774
5775         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5776         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5778         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5779
5780         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5781         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5783         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5784
5785         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5786         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5787
5788         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5789         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5791         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5792
5793         hr = IDirect3DDevice9_EndScene(device);
5794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5795     }
5796
5797     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5798     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5799
5800     color = getPixelColor(device, 160, 360);
5801     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5802     color = getPixelColor(device, 480, 360);
5803     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5804     color = getPixelColor(device, 160, 120);
5805     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5806     color = getPixelColor(device, 480, 160);
5807     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5808
5809     IDirect3DVertexShader9_Release(shader_sge_vec);
5810     IDirect3DVertexShader9_Release(shader_slt_vec);
5811     IDirect3DVertexShader9_Release(shader_sge_scalar);
5812     IDirect3DVertexShader9_Release(shader_slt_scalar);
5813 }
5814
5815 void test_vshader_input(IDirect3DDevice9 *device)
5816 {
5817     DWORD swapped_shader_code_3[] = {
5818         0xfffe0300,                                         /* vs_3_0               */
5819         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5820         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5821         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5822         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5823         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5824         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5825         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5826         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5827         0x0000ffff                                          /* end                  */
5828     };
5829     DWORD swapped_shader_code_1[] = {
5830         0xfffe0101,                                         /* vs_1_1               */
5831         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5832         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5833         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5834         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5835         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5836         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5837         0x0000ffff                                          /* end                  */
5838     };
5839     DWORD swapped_shader_code_2[] = {
5840         0xfffe0200,                                         /* vs_2_0               */
5841         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5842         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5843         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5844         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5845         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5846         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5847         0x0000ffff                                          /* end                  */
5848     };
5849     DWORD texcoord_color_shader_code_3[] = {
5850         0xfffe0300,                                         /* vs_3_0               */
5851         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5852         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5853         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5854         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5855         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5856         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5857         0x0000ffff                                          /* end                  */
5858     };
5859     DWORD texcoord_color_shader_code_2[] = {
5860         0xfffe0200,                                         /* vs_2_0               */
5861         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5862         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5863         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5864         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5865         0x0000ffff                                          /* end                  */
5866     };
5867     DWORD texcoord_color_shader_code_1[] = {
5868         0xfffe0101,                                         /* vs_1_1               */
5869         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5870         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5871         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5872         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5873         0x0000ffff                                          /* end                  */
5874     };
5875     DWORD color_color_shader_code_3[] = {
5876         0xfffe0300,                                         /* vs_3_0               */
5877         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5878         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5879         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5880         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5881         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5882         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5883         0x0000ffff                                          /* end                  */
5884     };
5885     DWORD color_color_shader_code_2[] = {
5886         0xfffe0200,                                         /* vs_2_0               */
5887         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5888         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5889         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5890         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5891         0x0000ffff                                          /* end                  */
5892     };
5893     DWORD color_color_shader_code_1[] = {
5894         0xfffe0101,                                         /* vs_1_1               */
5895         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5896         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5897         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5898         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5899         0x0000ffff                                          /* end                  */
5900     };
5901     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5902     HRESULT hr;
5903     DWORD color, r, g, b;
5904     float quad1[] =  {
5905         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5906          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5907         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5908          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5909     };
5910     float quad2[] =  {
5911          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5912          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5913          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5914          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5915     };
5916     float quad3[] =  {
5917         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5918          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5919         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5920          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5921     };
5922     float quad4[] =  {
5923          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5924          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5925          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5926          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5927     };
5928     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5929         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5930         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5931         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5932         D3DDECL_END()
5933     };
5934     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5935         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5936         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5937         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5938         D3DDECL_END()
5939     };
5940     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5941         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5942         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5943         D3DDECL_END()
5944     };
5945     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
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,       2},
5949         D3DDECL_END()
5950     };
5951     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5952         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5953         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5954         D3DDECL_END()
5955     };
5956     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5957         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5958         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5959         D3DDECL_END()
5960     };
5961     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5962         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5963         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5964         D3DDECL_END()
5965     };
5966     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5967         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5968         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5969         D3DDECL_END()
5970     };
5971     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5972     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5973     unsigned int i;
5974     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5975     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5976
5977     struct vertex quad1_color[] =  {
5978        {-1.0,   -1.0,   0.1,    0x00ff8040},
5979        { 0.0,   -1.0,   0.1,    0x00ff8040},
5980        {-1.0,    0.0,   0.1,    0x00ff8040},
5981        { 0.0,    0.0,   0.1,    0x00ff8040}
5982     };
5983     struct vertex quad2_color[] =  {
5984        { 0.0,   -1.0,   0.1,    0x00ff8040},
5985        { 1.0,   -1.0,   0.1,    0x00ff8040},
5986        { 0.0,    0.0,   0.1,    0x00ff8040},
5987        { 1.0,    0.0,   0.1,    0x00ff8040}
5988     };
5989     struct vertex quad3_color[] =  {
5990        {-1.0,    0.0,   0.1,    0x00ff8040},
5991        { 0.0,    0.0,   0.1,    0x00ff8040},
5992        {-1.0,    1.0,   0.1,    0x00ff8040},
5993        { 0.0,    1.0,   0.1,    0x00ff8040}
5994     };
5995     float quad4_color[] =  {
5996          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5997          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5998          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5999          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6000     };
6001
6002     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6003     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6004     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6005     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6006     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6007     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6008     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6009     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6010
6011     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6012     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6013     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6014     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6015     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6016     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6017     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6018     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6019
6020     for(i = 1; i <= 3; i++) {
6021         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6022         if(i == 3) {
6023             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6024             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6025         } else if(i == 2){
6026             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6027             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6028         } else if(i == 1) {
6029             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6030             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6031         }
6032
6033         hr = IDirect3DDevice9_BeginScene(device);
6034         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6035         if(SUCCEEDED(hr))
6036         {
6037             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6038             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6039
6040             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6041             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6042             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6043             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6044
6045             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6046             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6047             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6048             if(i == 3 || i == 2) {
6049                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6050             } else if(i == 1) {
6051                 /* Succeeds or fails, depending on SW or HW vertex processing */
6052                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6053             }
6054
6055             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6056             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6057             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6058             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6059
6060             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6061             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6062             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6063             if(i == 3 || i == 2) {
6064                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6065             } else if(i == 1) {
6066                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6067             }
6068
6069             hr = IDirect3DDevice9_EndScene(device);
6070             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6071         }
6072
6073         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6074         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6075
6076         if(i == 3 || i == 2) {
6077             color = getPixelColor(device, 160, 360);
6078             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6079                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6080
6081             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6082             color = getPixelColor(device, 480, 360);
6083             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6084                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6085             color = getPixelColor(device, 160, 120);
6086             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6087             ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
6088                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6089
6090             color = getPixelColor(device, 480, 160);
6091             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6092         } else if(i == 1) {
6093             color = getPixelColor(device, 160, 360);
6094             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6095                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6096             color = getPixelColor(device, 480, 360);
6097             /* Accept the clear color as well in this case, since SW VP returns an error */
6098             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6099             color = getPixelColor(device, 160, 120);
6100             ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6101                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6102             color = getPixelColor(device, 480, 160);
6103             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6104         }
6105
6106         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6107         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6108
6109         /* Now find out if the whole streams are re-read, or just the last active value for the
6110          * vertices is used.
6111          */
6112         hr = IDirect3DDevice9_BeginScene(device);
6113         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6114         if(SUCCEEDED(hr))
6115         {
6116             float quad1_modified[] =  {
6117                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6118                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6119                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6120                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6121             };
6122             float quad2_modified[] =  {
6123                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6124                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6125                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6126                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6127             };
6128
6129             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6130             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6131
6132             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6133             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6134             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6135             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6136
6137             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6138             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6139             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6140             if(i == 3 || i == 2) {
6141                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6142             } else if(i == 1) {
6143                 /* Succeeds or fails, depending on SW or HW vertex processing */
6144                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6145             }
6146
6147             hr = IDirect3DDevice9_EndScene(device);
6148             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6149         }
6150         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6151         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6152
6153         color = getPixelColor(device, 480, 350);
6154         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6155          * as well.
6156          *
6157          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6158          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6159          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6160          * refrast's result.
6161          *
6162          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6163          */
6164         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6165            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6166         color = getPixelColor(device, 160, 120);
6167
6168         IDirect3DDevice9_SetVertexShader(device, NULL);
6169         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6170
6171         IDirect3DVertexShader9_Release(swapped_shader);
6172     }
6173
6174     for(i = 1; i <= 3; i++) {
6175         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6176         if(i == 3) {
6177             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6178             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6179             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6180             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6181         } else if(i == 2){
6182             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6183             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6184             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6185             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6186         } else if(i == 1) {
6187             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6188             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6189             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6190             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6191         }
6192
6193         hr = IDirect3DDevice9_BeginScene(device);
6194         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6195         if(SUCCEEDED(hr))
6196         {
6197             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6198             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6199             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6200             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6201             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6202             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6203
6204             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6205             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6206
6207             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6208             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6209             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6210             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6211             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6212             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6213
6214             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6215             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6216             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6217             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6218             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6219             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6220
6221             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6222             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6223             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6224             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6225
6226             hr = IDirect3DDevice9_EndScene(device);
6227             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6228         }
6229         IDirect3DDevice9_SetVertexShader(device, NULL);
6230         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6231
6232         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6233         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6234
6235         color = getPixelColor(device, 160, 360);
6236         r = (color & 0x00ff0000) >> 16;
6237         g = (color & 0x0000ff00) >>  8;
6238         b = (color & 0x000000ff) >>  0;
6239         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6240            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6241         color = getPixelColor(device, 480, 360);
6242         r = (color & 0x00ff0000) >> 16;
6243         g = (color & 0x0000ff00) >>  8;
6244         b = (color & 0x000000ff) >>  0;
6245         ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6246            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6247         color = getPixelColor(device, 160, 120);
6248         r = (color & 0x00ff0000) >> 16;
6249         g = (color & 0x0000ff00) >>  8;
6250         b = (color & 0x000000ff) >>  0;
6251         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6252            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6253         color = getPixelColor(device, 480, 160);
6254         r = (color & 0x00ff0000) >> 16;
6255         g = (color & 0x0000ff00) >>  8;
6256         b = (color & 0x000000ff) >>  0;
6257         ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6258            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6259
6260         IDirect3DVertexShader9_Release(texcoord_color_shader);
6261         IDirect3DVertexShader9_Release(color_color_shader);
6262     }
6263
6264     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6265     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6266     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6267     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6268
6269     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6270     IDirect3DVertexDeclaration9_Release(decl_color_color);
6271     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6272     IDirect3DVertexDeclaration9_Release(decl_color_float);
6273 }
6274
6275 static void srgbtexture_test(IDirect3DDevice9 *device)
6276 {
6277     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6278      * texture stage state to render a quad using that texture.  The resulting
6279      * color components should be 0x36 (~ 0.21), per this formula:
6280      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6281      * This is true where srgb_color > 0.04045.
6282      */
6283     IDirect3D9 *d3d = NULL;
6284     HRESULT hr;
6285     LPDIRECT3DTEXTURE9 texture = NULL;
6286     LPDIRECT3DSURFACE9 surface = NULL;
6287     D3DLOCKED_RECT lr;
6288     DWORD color;
6289     float quad[] = {
6290         -1.0,       1.0,       0.0,     0.0,    0.0,
6291          1.0,       1.0,       0.0,     1.0,    0.0,
6292         -1.0,      -1.0,       0.0,     0.0,    1.0,
6293          1.0,      -1.0,       0.0,     1.0,    1.0,
6294     };
6295
6296
6297     memset(&lr, 0, sizeof(lr));
6298     IDirect3DDevice9_GetDirect3D(device, &d3d);
6299     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6300                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6301                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6302         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6303         goto out;
6304     }
6305
6306     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6307                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6308                                         &texture, NULL);
6309     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6310     if(!texture) {
6311         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6312         goto out;
6313     }
6314     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6315     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6316
6317     fill_surface(surface, 0xff7f7f7f);
6318     IDirect3DSurface9_Release(surface);
6319
6320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6322     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6323     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6324
6325     hr = IDirect3DDevice9_BeginScene(device);
6326     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6327     if(SUCCEEDED(hr))
6328     {
6329         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6330         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6331
6332         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6333         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6334
6335
6336         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6337         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6338
6339         hr = IDirect3DDevice9_EndScene(device);
6340         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6341     }
6342
6343     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6344     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6345     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6346     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6347
6348     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6349     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6350
6351     color = getPixelColor(device, 320, 240);
6352     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6353
6354 out:
6355     if(texture) IDirect3DTexture9_Release(texture);
6356     IDirect3D9_Release(d3d);
6357 }
6358
6359 static void shademode_test(IDirect3DDevice9 *device)
6360 {
6361     /* Render a quad and try all of the different fixed function shading models. */
6362     HRESULT hr;
6363     DWORD color0, color1;
6364     DWORD color0_gouraud = 0, color1_gouraud = 0;
6365     BYTE r, g, b;
6366     DWORD shademode = D3DSHADE_FLAT;
6367     DWORD primtype = D3DPT_TRIANGLESTRIP;
6368     LPVOID data = NULL;
6369     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6370     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6371     UINT i, j;
6372     struct vertex quad_strip[] =
6373     {
6374         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6375         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6376         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6377         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6378     };
6379     struct vertex quad_list[] =
6380     {
6381         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6382         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6383         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6384
6385         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6386         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6387         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6388     };
6389
6390     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6391                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6392     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6393     if (FAILED(hr)) goto bail;
6394
6395     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6396                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6397     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6398     if (FAILED(hr)) goto bail;
6399
6400     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6401     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6402
6403     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6404     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6405
6406     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6407     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6408     memcpy(data, quad_strip, sizeof(quad_strip));
6409     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6410     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6411
6412     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6413     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6414     memcpy(data, quad_list, sizeof(quad_list));
6415     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6416     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6417
6418     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6419      * the color fixups we have to do for FLAT shading will be dependent on that. */
6420     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6421     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6422
6423     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6424     for (j=0; j<2; j++) {
6425
6426         /* Inner loop just changes the D3DRS_SHADEMODE */
6427         for (i=0; i<3; i++) {
6428             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6429             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6430
6431             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6432             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6433
6434             hr = IDirect3DDevice9_BeginScene(device);
6435             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6436             if(SUCCEEDED(hr))
6437             {
6438                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6439                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6440
6441                 hr = IDirect3DDevice9_EndScene(device);
6442                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6443             }
6444
6445             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6446             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6447
6448             /* Sample two spots from the output */
6449             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6450             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6451             switch(shademode) {
6452                 case D3DSHADE_FLAT:
6453                     /* Should take the color of the first vertex of each triangle */
6454                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6455                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6456                     shademode = D3DSHADE_GOURAUD;
6457                     break;
6458                 case D3DSHADE_GOURAUD:
6459                     /* Should be an interpolated blend */
6460
6461                     r = (color0 & 0x00ff0000) >> 16;
6462                     g = (color0 & 0x0000ff00) >>  8;
6463                     b = (color0 & 0x000000ff);
6464                     ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6465                        "GOURAUD shading has color0 %08x, expected 0x000dca28\n", color0);
6466                     r = (color1 & 0x00ff0000) >> 16;
6467                     g = (color1 & 0x0000ff00) >>  8;
6468                     b = (color1 & 0x000000ff);
6469                     ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6470                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6471
6472                     color0_gouraud = color0;
6473                     color1_gouraud = color1;
6474
6475                     shademode = D3DSHADE_PHONG;
6476                     break;
6477                 case D3DSHADE_PHONG:
6478                     /* Should be the same as GOURAUD, since no hardware implements this */
6479                     r = (color0 & 0x00ff0000) >> 16;
6480                     g = (color0 & 0x0000ff00) >>  8;
6481                     b = (color0 & 0x000000ff);
6482                     ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6483                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6484                     r = (color1 & 0x00ff0000) >> 16;
6485                     g = (color1 & 0x0000ff00) >>  8;
6486                     b = (color1 & 0x000000ff);
6487                     ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6488                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6489
6490                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6491                             color0_gouraud, color0);
6492                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6493                             color1_gouraud, color1);
6494                     break;
6495             }
6496         }
6497         /* Now, do it all over again with a TRIANGLELIST */
6498         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6499         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6500         primtype = D3DPT_TRIANGLELIST;
6501         shademode = D3DSHADE_FLAT;
6502     }
6503
6504 bail:
6505     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6506     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6507     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6508     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6509
6510     if (vb_strip)
6511         IDirect3DVertexBuffer9_Release(vb_strip);
6512     if (vb_list)
6513         IDirect3DVertexBuffer9_Release(vb_list);
6514 }
6515
6516
6517 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6518 {
6519     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6520      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6521      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6522      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6523      * 0.73
6524      *
6525      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6526      * so use shaders for this task
6527      */
6528     IDirect3DPixelShader9 *pshader;
6529     IDirect3DVertexShader9 *vshader;
6530     IDirect3D9 *d3d;
6531     DWORD vshader_code[] = {
6532         0xfffe0101,                                                             /* vs_1_1                       */
6533         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6534         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6535         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6536         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6537         0x0000ffff                                                              /* end                          */
6538     };
6539     DWORD pshader_code[] = {
6540         0xffff0101,                                                             /* ps_1_1                       */
6541         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6542         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6543         0x0000ffff                                                              /* end                          */
6544     };
6545     const float quad[] = {
6546        -1.0,   -1.0,    0.1,
6547         1.0,   -1.0,    0.1,
6548        -1.0,    1.0,    0.1,
6549         1.0,    1.0,    0.1
6550     };
6551     HRESULT hr;
6552     DWORD color;
6553
6554     IDirect3DDevice9_GetDirect3D(device, &d3d);
6555     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6556                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6557                                     D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
6558         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6559         IDirect3D9_Release(d3d);
6560         return;
6561     }
6562     IDirect3D9_Release(d3d);
6563
6564     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6565     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6566
6567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6568     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6569     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6570     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6572     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6574     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6576     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6577
6578     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6579     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6580     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6581     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6582     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6583     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6584     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6585     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6586     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6587     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6588
6589     hr = IDirect3DDevice9_BeginScene(device);
6590     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6591     if(SUCCEEDED(hr)) {
6592         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6593         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6594
6595         hr = IDirect3DDevice9_EndScene(device);
6596         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6597     }
6598
6599     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6600     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6601     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6602     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6603     IDirect3DPixelShader9_Release(pshader);
6604     IDirect3DVertexShader9_Release(vshader);
6605
6606     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6607     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6608     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6609     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6610
6611     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6612     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6613     color = getPixelColor(device, 160, 360);
6614     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6615        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6616 }
6617
6618 static void alpha_test(IDirect3DDevice9 *device)
6619 {
6620     HRESULT hr;
6621     IDirect3DTexture9 *offscreenTexture;
6622     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6623     DWORD color, red, green, blue;
6624
6625     struct vertex quad1[] =
6626     {
6627         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6628         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6629         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6630         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6631     };
6632     struct vertex quad2[] =
6633     {
6634         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6635         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6636         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6637         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6638     };
6639     static const float composite_quad[][5] = {
6640         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6641         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6642         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6643         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6644     };
6645
6646     /* Clear the render target with alpha = 0.5 */
6647     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6648     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6649
6650     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6651     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6652
6653     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6654     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6655     if(!backbuffer) {
6656         goto out;
6657     }
6658
6659     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6660     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6661     if(!offscreen) {
6662         goto out;
6663     }
6664
6665     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6666     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6667
6668     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6669     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6670     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6671     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6672     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6673     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6674     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6675     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6676     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6677     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6678
6679     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6680     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6681     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6682
6683         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
6684          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
6685          * the input alpha
6686          *
6687          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
6688          * They give essentially ZERO and ONE blend factors
6689          */
6690         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6691         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6692         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6693         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6694         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6695         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6696
6697         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6698         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6699         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6700         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6701         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6702         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6703
6704         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
6705          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
6706          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
6707          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
6708          * vertices
6709          */
6710         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6711         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6712         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6713         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6714
6715         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6716         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6717         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6718         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6719         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6720         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6721
6722         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6723         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6724         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6725         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6726         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6727         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6728
6729         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6730         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6731
6732         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6733          * Disable alpha blending for the final composition
6734          */
6735         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6736         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6737         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6738         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6739
6740         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6741         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6742         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6743         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6744         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6745         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6746
6747         hr = IDirect3DDevice9_EndScene(device);
6748         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6749     }
6750
6751     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6752
6753     color = getPixelColor(device, 160, 360);
6754     red =   (color & 0x00ff0000) >> 16;
6755     green = (color & 0x0000ff00) >>  8;
6756     blue =  (color & 0x000000ff);
6757     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6758        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6759
6760     color = getPixelColor(device, 160, 120);
6761     red =   (color & 0x00ff0000) >> 16;
6762     green = (color & 0x0000ff00) >>  8;
6763     blue =  (color & 0x000000ff);
6764     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6765        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6766
6767     color = getPixelColor(device, 480, 360);
6768     red =   (color & 0x00ff0000) >> 16;
6769     green = (color & 0x0000ff00) >>  8;
6770     blue =  (color & 0x000000ff);
6771     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6772        "SRCALPHA on texture returned color %08x, expected bar\n", color);
6773
6774     color = getPixelColor(device, 480, 120);
6775     red =   (color & 0x00ff0000) >> 16;
6776     green = (color & 0x0000ff00) >>  8;
6777     blue =  (color & 0x000000ff);
6778     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6779        "DSTALPHA on texture returned color %08x, expected 0x00800080\n", color);
6780
6781     out:
6782     /* restore things */
6783     if(backbuffer) {
6784         IDirect3DSurface9_Release(backbuffer);
6785     }
6786     if(offscreenTexture) {
6787         IDirect3DTexture9_Release(offscreenTexture);
6788     }
6789     if(offscreen) {
6790         IDirect3DSurface9_Release(offscreen);
6791     }
6792 }
6793
6794 struct vertex_shortcolor {
6795     float x, y, z;
6796     unsigned short r, g, b, a;
6797 };
6798 struct vertex_floatcolor {
6799     float x, y, z;
6800     float r, g, b, a;
6801 };
6802
6803 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6804 {
6805     HRESULT hr;
6806     BOOL s_ok, ub_ok, f_ok;
6807     DWORD color, size, i;
6808     void *data;
6809     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6810         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6811         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6812         D3DDECL_END()
6813     };
6814     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6815         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6816         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6817         D3DDECL_END()
6818     };
6819     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6820         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6821         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6822         D3DDECL_END()
6823     };
6824     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6825         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6826         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6827         D3DDECL_END()
6828     };
6829     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6830         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6831         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6832         D3DDECL_END()
6833     };
6834     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6835         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6836         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6837         D3DDECL_END()
6838     };
6839     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6840         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6841         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6842         D3DDECL_END()
6843     };
6844     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6845     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6846     IDirect3DVertexBuffer9 *vb, *vb2;
6847     struct vertex quad1[] =                             /* D3DCOLOR */
6848     {
6849         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6850         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6851         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6852         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6853     };
6854     struct vertex quad2[] =                             /* UBYTE4N */
6855     {
6856         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6857         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6858         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6859         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6860     };
6861     struct vertex_shortcolor quad3[] =                  /* short */
6862     {
6863         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6864         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6865         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6866         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6867     };
6868     struct vertex_floatcolor quad4[] =
6869     {
6870         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6871         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6872         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6873         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6874     };
6875     DWORD colors[] = {
6876         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6877         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6878         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6879         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6880         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6881         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6882         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6883         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6884         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6885         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6886         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6887         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6888         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6889         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6890         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6891         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6892     };
6893     float quads[] = {
6894         -1.0,   -1.0,     0.1,
6895         -1.0,    0.0,     0.1,
6896          0.0,   -1.0,     0.1,
6897          0.0,    0.0,     0.1,
6898
6899          0.0,   -1.0,     0.1,
6900          0.0,    0.0,     0.1,
6901          1.0,   -1.0,     0.1,
6902          1.0,    0.0,     0.1,
6903
6904          0.0,    0.0,     0.1,
6905          0.0,    1.0,     0.1,
6906          1.0,    0.0,     0.1,
6907          1.0,    1.0,     0.1,
6908
6909         -1.0,    0.0,     0.1,
6910         -1.0,    1.0,     0.1,
6911          0.0,    0.0,     0.1,
6912          0.0,    1.0,     0.1
6913     };
6914     struct tvertex quad_transformed[] = {
6915        {  90,    110,     0.1,      2.0,        0x00ffff00},
6916        { 570,    110,     0.1,      2.0,        0x00ffff00},
6917        {  90,    300,     0.1,      2.0,        0x00ffff00},
6918        { 570,    300,     0.1,      2.0,        0x00ffff00}
6919     };
6920     D3DCAPS9 caps;
6921
6922     memset(&caps, 0, sizeof(caps));
6923     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6924     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6925
6926     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6927     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6928
6929     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6930     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6931     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6932     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6933     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6934     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6935     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6936         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6937         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6938         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6939         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6940     } else {
6941         trace("D3DDTCAPS_UBYTE4N not supported\n");
6942         dcl_ubyte_2 = NULL;
6943         dcl_ubyte = NULL;
6944     }
6945     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6946     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6947     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6948     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6949
6950     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6951     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6952                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6953     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6954
6955     hr = IDirect3DDevice9_BeginScene(device);
6956     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6957     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6958     if(SUCCEEDED(hr)) {
6959         if(dcl_color) {
6960             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6961             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6962             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6963             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6964         }
6965
6966         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6967          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6968          * using software vertex processing. Doh!
6969          */
6970         if(dcl_ubyte) {
6971             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6972             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6973             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6974             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6975             ub_ok = SUCCEEDED(hr);
6976         }
6977
6978         if(dcl_short) {
6979             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6980             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6981             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6982             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6983             s_ok = SUCCEEDED(hr);
6984         }
6985
6986         if(dcl_float) {
6987             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6988             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6989             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6990             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6991             f_ok = SUCCEEDED(hr);
6992         }
6993
6994         hr = IDirect3DDevice9_EndScene(device);
6995         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6996     }
6997
6998     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6999     if(dcl_short) {
7000         color = getPixelColor(device, 480, 360);
7001         ok(color == 0x000000ff || !s_ok,
7002            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7003     }
7004     if(dcl_ubyte) {
7005         color = getPixelColor(device, 160, 120);
7006         ok(color == 0x0000ffff || !ub_ok,
7007            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7008     }
7009     if(dcl_color) {
7010         color = getPixelColor(device, 160, 360);
7011         ok(color == 0x00ffff00,
7012            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7013     }
7014     if(dcl_float) {
7015         color = getPixelColor(device, 480, 120);
7016         ok(color == 0x00ff0000 || !f_ok,
7017            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7018     }
7019
7020     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7021      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7022      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7023      * whether the immediate mode code works
7024      */
7025     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7026     hr = IDirect3DDevice9_BeginScene(device);
7027     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7028     if(SUCCEEDED(hr)) {
7029         if(dcl_color) {
7030             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7031             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7032             memcpy(data, quad1, sizeof(quad1));
7033             hr = IDirect3DVertexBuffer9_Unlock(vb);
7034             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7035             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7036             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7037             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7038             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7039             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7040             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7041         }
7042
7043         if(dcl_ubyte) {
7044             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7045             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7046             memcpy(data, quad2, sizeof(quad2));
7047             hr = IDirect3DVertexBuffer9_Unlock(vb);
7048             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7049             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7050             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7051             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7052             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7053             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7054             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7055                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7056             ub_ok = SUCCEEDED(hr);
7057         }
7058
7059         if(dcl_short) {
7060             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7061             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7062             memcpy(data, quad3, sizeof(quad3));
7063             hr = IDirect3DVertexBuffer9_Unlock(vb);
7064             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7065             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7066             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7067             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7068             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7069             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7070             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7071                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7072             s_ok = SUCCEEDED(hr);
7073         }
7074
7075         if(dcl_float) {
7076             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7077             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7078             memcpy(data, quad4, sizeof(quad4));
7079             hr = IDirect3DVertexBuffer9_Unlock(vb);
7080             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7081             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7082             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7083             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7084             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7085             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7086             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7087                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7088             f_ok = SUCCEEDED(hr);
7089         }
7090
7091         hr = IDirect3DDevice9_EndScene(device);
7092         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7093     }
7094
7095     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7096     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7097     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7098     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7099
7100     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7101     if(dcl_short) {
7102         color = getPixelColor(device, 480, 360);
7103         ok(color == 0x000000ff || !s_ok,
7104            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7105     }
7106     if(dcl_ubyte) {
7107         color = getPixelColor(device, 160, 120);
7108         ok(color == 0x0000ffff || !ub_ok,
7109            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7110     }
7111     if(dcl_color) {
7112         color = getPixelColor(device, 160, 360);
7113         ok(color == 0x00ffff00,
7114            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7115     }
7116     if(dcl_float) {
7117         color = getPixelColor(device, 480, 120);
7118         ok(color == 0x00ff0000 || !f_ok,
7119            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7120     }
7121
7122     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7123     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7124
7125     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7126     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7127     memcpy(data, quad_transformed, sizeof(quad_transformed));
7128     hr = IDirect3DVertexBuffer9_Unlock(vb);
7129     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7130
7131     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7132     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7133
7134     hr = IDirect3DDevice9_BeginScene(device);
7135     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7136     if(SUCCEEDED(hr)) {
7137         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7138         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7139         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7140         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7141
7142         hr = IDirect3DDevice9_EndScene(device);
7143         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7144     }
7145
7146     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7147     color = getPixelColor(device, 88, 108);
7148     ok(color == 0x000000ff,
7149        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7150     color = getPixelColor(device, 92, 108);
7151     ok(color == 0x000000ff,
7152        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7153     color = getPixelColor(device, 88, 112);
7154     ok(color == 0x000000ff,
7155        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7156     color = getPixelColor(device, 92, 112);
7157     ok(color == 0x00ffff00,
7158        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7159
7160     color = getPixelColor(device, 568, 108);
7161     ok(color == 0x000000ff,
7162        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7163     color = getPixelColor(device, 572, 108);
7164     ok(color == 0x000000ff,
7165        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7166     color = getPixelColor(device, 568, 112);
7167     ok(color == 0x00ffff00,
7168        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7169     color = getPixelColor(device, 572, 112);
7170     ok(color == 0x000000ff,
7171        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7172
7173     color = getPixelColor(device, 88, 298);
7174     ok(color == 0x000000ff,
7175        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7176     color = getPixelColor(device, 92, 298);
7177     ok(color == 0x00ffff00,
7178        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7179     color = getPixelColor(device, 88, 302);
7180     ok(color == 0x000000ff,
7181        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7182     color = getPixelColor(device, 92, 302);
7183     ok(color == 0x000000ff,
7184        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7185
7186     color = getPixelColor(device, 568, 298);
7187     ok(color == 0x00ffff00,
7188        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7189     color = getPixelColor(device, 572, 298);
7190     ok(color == 0x000000ff,
7191        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7192     color = getPixelColor(device, 568, 302);
7193     ok(color == 0x000000ff,
7194        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7195     color = getPixelColor(device, 572, 302);
7196     ok(color == 0x000000ff,
7197        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7198
7199     /* This test is pointless without those two declarations: */
7200     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7201         skip("color-ubyte switching test declarations aren't supported\n");
7202         goto out;
7203     }
7204
7205     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7206     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7207     memcpy(data, quads, sizeof(quads));
7208     hr = IDirect3DVertexBuffer9_Unlock(vb);
7209     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7210     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7211                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7212     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7213     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7214     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7215     memcpy(data, colors, sizeof(colors));
7216     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7217     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7218
7219     for(i = 0; i < 2; i++) {
7220         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7221         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7222
7223         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7224         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7225         if(i == 0) {
7226             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7227         } else {
7228             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7229         }
7230         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7231
7232         hr = IDirect3DDevice9_BeginScene(device);
7233         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7234         ub_ok = FALSE;
7235         if(SUCCEEDED(hr)) {
7236             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7237             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7238             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7239             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7240                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7241             ub_ok = SUCCEEDED(hr);
7242
7243             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7244             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7245             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7246             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7247
7248             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7249             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7250             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7251             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7252                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7253             ub_ok = (SUCCEEDED(hr) && ub_ok);
7254
7255             hr = IDirect3DDevice9_EndScene(device);
7256             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7257         }
7258
7259         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7260         if(i == 0) {
7261             color = getPixelColor(device, 480, 360);
7262             ok(color == 0x00ff0000,
7263                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7264             color = getPixelColor(device, 160, 120);
7265             ok(color == 0x00ffffff,
7266                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7267             color = getPixelColor(device, 160, 360);
7268             ok(color == 0x000000ff || !ub_ok,
7269                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7270             color = getPixelColor(device, 480, 120);
7271             ok(color == 0x000000ff || !ub_ok,
7272                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7273         } else {
7274             color = getPixelColor(device, 480, 360);
7275             ok(color == 0x000000ff,
7276                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7277             color = getPixelColor(device, 160, 120);
7278             ok(color == 0x00ffffff,
7279                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7280             color = getPixelColor(device, 160, 360);
7281             ok(color == 0x00ff0000 || !ub_ok,
7282                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7283             color = getPixelColor(device, 480, 120);
7284             ok(color == 0x00ff0000 || !ub_ok,
7285                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7286         }
7287     }
7288
7289     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7290     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7291     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7292     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7293     IDirect3DVertexBuffer9_Release(vb2);
7294
7295     out:
7296     IDirect3DVertexBuffer9_Release(vb);
7297     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7298     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7299     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7300     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7301     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7302     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7303     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7304 }
7305
7306 struct vertex_float16color {
7307     float x, y, z;
7308     DWORD c1, c2;
7309 };
7310
7311 static void test_vshader_float16(IDirect3DDevice9 *device)
7312 {
7313     HRESULT hr;
7314     DWORD color;
7315     void *data;
7316     static const D3DVERTEXELEMENT9 decl_elements[] = {
7317         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7318         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7319         D3DDECL_END()
7320     };
7321     IDirect3DVertexDeclaration9 *vdecl = NULL;
7322     IDirect3DVertexBuffer9 *buffer = NULL;
7323     IDirect3DVertexShader9 *shader;
7324     DWORD shader_code[] = {
7325         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7326         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7327         0x90e40001, 0x0000ffff
7328     };
7329     struct vertex_float16color quad[] = {
7330         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7331         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7332         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7333         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7334
7335         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7336         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7337         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7338         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7339
7340         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7341         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7342         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7343         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7344
7345         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7346         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7347         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7348         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7349     };
7350
7351     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7352     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7353
7354     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7355     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7356     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7357     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7358     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7359     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7360
7361     hr = IDirect3DDevice9_BeginScene(device);
7362     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7363     if(SUCCEEDED(hr)) {
7364         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7365         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7366         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7367         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7368         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7369         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7370         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7371         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7372         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7373         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7374
7375         hr = IDirect3DDevice9_EndScene(device);
7376         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7377     }
7378     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7379     color = getPixelColor(device, 480, 360);
7380     ok(color == 0x00ff0000,
7381        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7382     color = getPixelColor(device, 160, 120);
7383     ok(color == 0x00000000,
7384        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7385     color = getPixelColor(device, 160, 360);
7386     ok(color == 0x0000ff00,
7387        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7388     color = getPixelColor(device, 480, 120);
7389     ok(color == 0x000000ff,
7390        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7391
7392     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7393     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7394
7395     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7396                                              D3DPOOL_MANAGED, &buffer, NULL);
7397     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7398     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7399     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7400     memcpy(data, quad, sizeof(quad));
7401     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7402     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7403     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7404     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7405
7406     hr = IDirect3DDevice9_BeginScene(device);
7407     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7408     if(SUCCEEDED(hr)) {
7409             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7410             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7411             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7412             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7413             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7414             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7415             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7416             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7417
7418             hr = IDirect3DDevice9_EndScene(device);
7419             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7420     }
7421
7422     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7423     color = getPixelColor(device, 480, 360);
7424     ok(color == 0x00ff0000,
7425        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7426     color = getPixelColor(device, 160, 120);
7427     ok(color == 0x00000000,
7428        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7429     color = getPixelColor(device, 160, 360);
7430     ok(color == 0x0000ff00,
7431        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7432     color = getPixelColor(device, 480, 120);
7433     ok(color == 0x000000ff,
7434        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7435
7436     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7437     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7438     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7439     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7440     IDirect3DDevice9_SetVertexShader(device, NULL);
7441     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7442
7443     IDirect3DVertexDeclaration9_Release(vdecl);
7444     IDirect3DVertexShader9_Release(shader);
7445     IDirect3DVertexBuffer9_Release(buffer);
7446 }
7447
7448 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7449 {
7450     D3DCAPS9 caps;
7451     IDirect3DTexture9 *texture;
7452     HRESULT hr;
7453     D3DLOCKED_RECT rect;
7454     unsigned int x, y;
7455     DWORD *dst, color;
7456     const float quad[] = {
7457         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7458          1.0,   -1.0,   0.1,    1.2,   -0.2,
7459         -1.0,    1.0,   0.1,   -0.2,    1.2,
7460          1.0,    1.0,   0.1,    1.2,    1.2
7461     };
7462     memset(&caps, 0, sizeof(caps));
7463
7464     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7465     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7466     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7467         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7468         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7469            "Card has conditional NP2 support without power of two restriction set\n");
7470         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7471         return;
7472     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7473         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7474         return;
7475     }
7476
7477     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7478     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7479
7480     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7481     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7482
7483     memset(&rect, 0, sizeof(rect));
7484     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7485     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7486     for(y = 0; y < 10; y++) {
7487         for(x = 0; x < 10; x++) {
7488             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7489             if(x == 0 || x == 9 || y == 0 || y == 9) {
7490                 *dst = 0x00ff0000;
7491             } else {
7492                 *dst = 0x000000ff;
7493             }
7494         }
7495     }
7496     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7497     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7498
7499     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7500     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7501     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7502     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7503     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7504     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7505     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7506     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7507
7508     hr = IDirect3DDevice9_BeginScene(device);
7509     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7510     if(SUCCEEDED(hr)) {
7511         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7512         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7513
7514         hr = IDirect3DDevice9_EndScene(device);
7515         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7516     }
7517
7518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7519
7520     color = getPixelColor(device,    1,  1);
7521     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7522     color = getPixelColor(device, 639, 479);
7523     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7524
7525     color = getPixelColor(device, 135, 101);
7526     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7527     color = getPixelColor(device, 140, 101);
7528     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7529     color = getPixelColor(device, 135, 105);
7530     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7531     color = getPixelColor(device, 140, 105);
7532     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7533
7534     color = getPixelColor(device, 135, 376);
7535     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7536     color = getPixelColor(device, 140, 376);
7537     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7538     color = getPixelColor(device, 135, 379);
7539     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7540     color = getPixelColor(device, 140, 379);
7541     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7542
7543     color = getPixelColor(device, 500, 101);
7544     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7545     color = getPixelColor(device, 504, 101);
7546     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7547     color = getPixelColor(device, 500, 105);
7548     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7549     color = getPixelColor(device, 504, 105);
7550     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7551
7552     color = getPixelColor(device, 500, 376);
7553     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7554     color = getPixelColor(device, 504, 376);
7555     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7556     color = getPixelColor(device, 500, 380);
7557     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7558     color = getPixelColor(device, 504, 380);
7559     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7560
7561     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7562     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7563     IDirect3DTexture9_Release(texture);
7564 }
7565
7566 static void vFace_register_test(IDirect3DDevice9 *device)
7567 {
7568     HRESULT hr;
7569     DWORD color;
7570     const DWORD shader_code[] = {
7571         0xffff0300,                                                             /* ps_3_0                     */
7572         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7573         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7574         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7575         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7576         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7577         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7578         0x0000ffff                                                              /* END                        */
7579     };
7580     IDirect3DPixelShader9 *shader;
7581     IDirect3DTexture9 *texture;
7582     IDirect3DSurface9 *surface, *backbuffer;
7583     const float quad[] = {
7584         -1.0,   -1.0,   0.1,
7585          1.0,   -1.0,   0.1,
7586         -1.0,    0.0,   0.1,
7587
7588          1.0,   -1.0,   0.1,
7589          1.0,    0.0,   0.1,
7590         -1.0,    0.0,   0.1,
7591
7592         -1.0,    0.0,   0.1,
7593         -1.0,    1.0,   0.1,
7594          1.0,    0.0,   0.1,
7595
7596          1.0,    0.0,   0.1,
7597         -1.0,    1.0,   0.1,
7598          1.0,    1.0,   0.1,
7599     };
7600     const float blit[] = {
7601          0.0,   -1.0,   0.1,    0.0,    0.0,
7602          1.0,   -1.0,   0.1,    1.0,    0.0,
7603          0.0,    1.0,   0.1,    0.0,    1.0,
7604          1.0,    1.0,   0.1,    1.0,    1.0,
7605     };
7606
7607     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7608     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7609     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7610     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7611     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7612     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7613     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7614     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7615     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7616     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7617     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7618     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7619
7620     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7621     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7622
7623     hr = IDirect3DDevice9_BeginScene(device);
7624     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7625     if(SUCCEEDED(hr)) {
7626         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7627         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7628         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7629         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7630         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7631         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7632         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7633         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7634         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7635         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7636         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7637
7638         /* Blit the texture onto the back buffer to make it visible */
7639         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7640         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7641         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7642         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7643         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7644         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7645         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7646         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7647         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7648         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7649
7650         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7651         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7652
7653         hr = IDirect3DDevice9_EndScene(device);
7654         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7655     }
7656
7657     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7658     color = getPixelColor(device, 160, 360);
7659     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7660     color = getPixelColor(device, 160, 120);
7661     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7662     color = getPixelColor(device, 480, 360);
7663     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7664     color = getPixelColor(device, 480, 120);
7665     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7666
7667     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7668     IDirect3DDevice9_SetTexture(device, 0, NULL);
7669     IDirect3DPixelShader9_Release(shader);
7670     IDirect3DSurface9_Release(surface);
7671     IDirect3DSurface9_Release(backbuffer);
7672     IDirect3DTexture9_Release(texture);
7673 }
7674
7675 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7676 {
7677     HRESULT hr;
7678     DWORD color;
7679     int i;
7680     D3DCAPS9 caps;
7681
7682     static const float quad[][7] = {
7683         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7684         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7685         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7686         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7687     };
7688
7689     static const D3DVERTEXELEMENT9 decl_elements[] = {
7690         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7691         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7692         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7693         D3DDECL_END()
7694     };
7695
7696     /* use asymmetric matrix to test loading */
7697     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7698
7699     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7700     IDirect3DTexture9           *texture            = NULL;
7701
7702     memset(&caps, 0, sizeof(caps));
7703     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7704     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7705     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7706         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7707         return;
7708     } else {
7709         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7710          * They report that it is not supported, but after that bump mapping works properly. So just test
7711          * if the format is generally supported, and check the BUMPENVMAP flag
7712          */
7713         IDirect3D9 *d3d9;
7714
7715         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7716         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7717                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7718         IDirect3D9_Release(d3d9);
7719         if(FAILED(hr)) {
7720             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7721             return;
7722         }
7723     }
7724
7725     /* Generate the textures */
7726     generate_bumpmap_textures(device);
7727
7728     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7729     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7730     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7731     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7732     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7733     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7734     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7735     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7736
7737     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7738     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7739     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7740     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7741     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7742     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7743
7744     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7745     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7746     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7747     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7748     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7749     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7750
7751     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7752     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7753
7754     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7755     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7756
7757     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7758     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7759
7760
7761     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7762     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7763     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7764     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7765
7766     hr = IDirect3DDevice9_BeginScene(device);
7767     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7768
7769     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7770     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7771
7772     hr = IDirect3DDevice9_EndScene(device);
7773     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7774
7775     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7776     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7777
7778     color = getPixelColor(device, 320-32, 240);
7779     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7780     color = getPixelColor(device, 320+32, 240);
7781     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7782     color = getPixelColor(device, 320, 240-32);
7783     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7784     color = getPixelColor(device, 320, 240+32);
7785     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7786     color = getPixelColor(device, 320, 240);
7787     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7788     color = getPixelColor(device, 320+32, 240+32);
7789     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7790     color = getPixelColor(device, 320-32, 240+32);
7791     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7792     color = getPixelColor(device, 320+32, 240-32);
7793     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7794     color = getPixelColor(device, 320-32, 240-32);
7795     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7796
7797     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7798     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7799     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7800
7801     for(i = 0; i < 2; i++) {
7802         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7803         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7804         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7805         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7806         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7807         IDirect3DTexture9_Release(texture); /* To destroy it */
7808     }
7809
7810     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7811     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7812     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7813     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814
7815 }
7816
7817 static void stencil_cull_test(IDirect3DDevice9 *device) {
7818     HRESULT hr;
7819     IDirect3DSurface9 *depthstencil = NULL;
7820     D3DSURFACE_DESC desc;
7821     float quad1[] = {
7822         -1.0,   -1.0,   0.1,
7823          0.0,   -1.0,   0.1,
7824         -1.0,    0.0,   0.1,
7825          0.0,    0.0,   0.1,
7826     };
7827     float quad2[] = {
7828          0.0,   -1.0,   0.1,
7829          1.0,   -1.0,   0.1,
7830          0.0,    0.0,   0.1,
7831          1.0,    0.0,   0.1,
7832     };
7833     float quad3[] = {
7834         0.0,    0.0,   0.1,
7835         1.0,    0.0,   0.1,
7836         0.0,    1.0,   0.1,
7837         1.0,    1.0,   0.1,
7838     };
7839     float quad4[] = {
7840         -1.0,    0.0,   0.1,
7841          0.0,    0.0,   0.1,
7842         -1.0,    1.0,   0.1,
7843          0.0,    1.0,   0.1,
7844     };
7845     struct vertex painter[] = {
7846        {-1.0,   -1.0,   0.0,    0x00000000},
7847        { 1.0,   -1.0,   0.0,    0x00000000},
7848        {-1.0,    1.0,   0.0,    0x00000000},
7849        { 1.0,    1.0,   0.0,    0x00000000},
7850     };
7851     WORD indices_cw[]  = {0, 1, 3};
7852     WORD indices_ccw[] = {0, 2, 3};
7853     unsigned int i;
7854     DWORD color;
7855
7856     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7857     if(depthstencil == NULL) {
7858         skip("No depth stencil buffer\n");
7859         return;
7860     }
7861     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7862     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7863     IDirect3DSurface9_Release(depthstencil);
7864     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7865         skip("No 4 or 8 bit stencil surface\n");
7866         return;
7867     }
7868
7869     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7870     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7871     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7872
7873     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7874     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7875     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7876     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7877     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7878     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7879     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7880     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7881
7882     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7883     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7884     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7885     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7886     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7887     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7888
7889     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7890     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7891     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7892     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7893
7894     /* First pass: Fill the stencil buffer with some values... */
7895     hr = IDirect3DDevice9_BeginScene(device);
7896     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7897     if(SUCCEEDED(hr))
7898     {
7899         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7900         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7901         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7902                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7903         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7904                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7905
7906         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7907         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7908         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7909         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7910         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7911                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7912         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7913                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7914
7915         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7916         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7917         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7918                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7919         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7920                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7921
7922         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7923         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7924         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7925                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7926         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7927                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7928
7929         hr = IDirect3DDevice9_EndScene(device);
7930         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7931     }
7932
7933     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7935     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7937     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7938     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7939     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7940     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7941     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7942     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7943     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7944     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7945     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7946
7947     /* 2nd pass: Make the stencil values visible */
7948     hr = IDirect3DDevice9_BeginScene(device);
7949     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7950     if(SUCCEEDED(hr))
7951     {
7952         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7953         for(i = 0; i < 16; i++) {
7954             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7955             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7956
7957             painter[0].diffuse = (i * 16); /* Creates shades of blue */
7958             painter[1].diffuse = (i * 16);
7959             painter[2].diffuse = (i * 16);
7960             painter[3].diffuse = (i * 16);
7961             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7962             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7963         }
7964         hr = IDirect3DDevice9_EndScene(device);
7965         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7966     }
7967
7968     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7969     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7970
7971     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7972     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7973
7974     color = getPixelColor(device, 160, 420);
7975     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7976     color = getPixelColor(device, 160, 300);
7977     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7978
7979     color = getPixelColor(device, 480, 420);
7980     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7981     color = getPixelColor(device, 480, 300);
7982     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
7983
7984     color = getPixelColor(device, 160, 180);
7985     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
7986     color = getPixelColor(device, 160, 60);
7987     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
7988
7989     color = getPixelColor(device, 480, 180);
7990     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
7991     color = getPixelColor(device, 480, 60);
7992     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7993 }
7994
7995 static void vpos_register_test(IDirect3DDevice9 *device)
7996 {
7997     HRESULT hr;
7998     DWORD color;
7999     const DWORD shader_code[] = {
8000     0xffff0300,                                                             /* ps_3_0                     */
8001     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8002     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8003     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8004     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8005     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8006     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8007     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8008     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8009     0x0000ffff                                                              /* end                        */
8010     };
8011     const DWORD shader_frac_code[] = {
8012     0xffff0300,                                                             /* ps_3_0                     */
8013     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8014     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8015     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8016     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8017     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8018     0x0000ffff                                                              /* end                        */
8019     };
8020     IDirect3DPixelShader9 *shader, *shader_frac;
8021     IDirect3DSurface9 *surface = NULL, *backbuffer;
8022     const float quad[] = {
8023         -1.0,   -1.0,   0.1,    0.0,    0.0,
8024          1.0,   -1.0,   0.1,    1.0,    0.0,
8025         -1.0,    1.0,   0.1,    0.0,    1.0,
8026          1.0,    1.0,   0.1,    1.0,    1.0,
8027     };
8028     D3DLOCKED_RECT lr;
8029     float constant[4] = {1.0, 0.0, 320, 240};
8030     DWORD *pos;
8031
8032     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8033     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8034     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8035     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8036     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8037     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8038     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8039     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8040     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8041     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8042     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8043     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8044
8045     hr = IDirect3DDevice9_BeginScene(device);
8046     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8047     if(SUCCEEDED(hr)) {
8048         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8049         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8050         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8051         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8052         hr = IDirect3DDevice9_EndScene(device);
8053         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8054     }
8055
8056     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8057     /* This has to be pixel exact */
8058     color = getPixelColor(device, 319, 239);
8059     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8060     color = getPixelColor(device, 320, 239);
8061     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8062     color = getPixelColor(device, 319, 240);
8063     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8064     color = getPixelColor(device, 320, 240);
8065     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8066
8067     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8068                                              &surface, NULL);
8069     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8070     hr = IDirect3DDevice9_BeginScene(device);
8071     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8072     if(SUCCEEDED(hr)) {
8073         constant[2] = 16; constant[3] = 16;
8074         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8075         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8076         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8077         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8078         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8079         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8080         hr = IDirect3DDevice9_EndScene(device);
8081         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8082     }
8083     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8084     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8085
8086     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8087     color = *pos & 0x00ffffff;
8088     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8089     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8090     color = *pos & 0x00ffffff;
8091     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8092     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8093     color = *pos & 0x00ffffff;
8094     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8095     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8096     color = *pos & 0x00ffffff;
8097     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8098
8099     hr = IDirect3DSurface9_UnlockRect(surface);
8100     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8101
8102     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8103      * have full control over the multisampling setting inside this test
8104      */
8105     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8106     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8107     hr = IDirect3DDevice9_BeginScene(device);
8108     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8109     if(SUCCEEDED(hr)) {
8110         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8111         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8112         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8113         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8114         hr = IDirect3DDevice9_EndScene(device);
8115         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8116     }
8117     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8118     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8119
8120     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8121     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8122
8123     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8124     color = *pos & 0x00ffffff;
8125     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8126
8127     hr = IDirect3DSurface9_UnlockRect(surface);
8128     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8129
8130     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8131     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8132     IDirect3DPixelShader9_Release(shader);
8133     IDirect3DPixelShader9_Release(shader_frac);
8134     if(surface) IDirect3DSurface9_Release(surface);
8135     IDirect3DSurface9_Release(backbuffer);
8136 }
8137
8138 static void pointsize_test(IDirect3DDevice9 *device)
8139 {
8140     HRESULT hr;
8141     D3DCAPS9 caps;
8142     D3DMATRIX matrix;
8143     D3DMATRIX identity;
8144     float ptsize, ptsize_orig;
8145     DWORD color;
8146
8147     const float vertices[] = {
8148         64,     64,     0.1,
8149         128,    64,     0.1,
8150         192,    64,     0.1,
8151         256,    64,     0.1,
8152         320,    64,     0.1,
8153         384,    64,     0.1
8154     };
8155
8156     /* 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 */
8157     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;
8158     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;
8159     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;
8160     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;
8161
8162     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;
8163     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;
8164     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;
8165     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;
8166
8167     memset(&caps, 0, sizeof(caps));
8168     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8169     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8170     if(caps.MaxPointSize < 32.0) {
8171         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8172         return;
8173     }
8174
8175     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8176     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8177     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8178     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8179     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8180     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8181     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8182     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8183
8184     hr = IDirect3DDevice9_BeginScene(device);
8185     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8186     if(SUCCEEDED(hr)) {
8187         ptsize = 16.0;
8188         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8189         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8191         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8192
8193         ptsize = 32.0;
8194         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8195         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8196         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8197         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8198
8199         ptsize = 31.5;
8200         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8201         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8203         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8204
8205         if(caps.MaxPointSize >= 64.0) {
8206             ptsize = 64.0;
8207             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8208             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8209             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8210             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8211
8212             ptsize = 63.75;
8213             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8214             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8215             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8216             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8217         }
8218
8219         ptsize = 1.0;
8220         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8221         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8222         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8223         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8224
8225         hr = IDirect3DDevice9_EndScene(device);
8226         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8227     }
8228     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8229     color = getPixelColor(device, 64-9, 64-9);
8230     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8231     color = getPixelColor(device, 64-8, 64-8);
8232     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8233     color = getPixelColor(device, 64-7, 64-7);
8234     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8235     color = getPixelColor(device, 64+7, 64+7);
8236     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8237     color = getPixelColor(device, 64+8, 64+8);
8238     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8239     color = getPixelColor(device, 64+9, 64+9);
8240     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8241
8242     color = getPixelColor(device, 128-17, 64-17);
8243     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8244     color = getPixelColor(device, 128-16, 64-16);
8245     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8246     color = getPixelColor(device, 128-15, 64-15);
8247     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8248     color = getPixelColor(device, 128+15, 64+15);
8249     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8250     color = getPixelColor(device, 128+16, 64+16);
8251     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8252     color = getPixelColor(device, 128+17, 64+17);
8253     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8254
8255     color = getPixelColor(device, 192-17, 64-17);
8256     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8257     color = getPixelColor(device, 192-16, 64-16);
8258     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8259     color = getPixelColor(device, 192-15, 64-15);
8260     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8261     color = getPixelColor(device, 192+15, 64+15);
8262     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8263     color = getPixelColor(device, 192+16, 64+16);
8264     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8265     color = getPixelColor(device, 192+17, 64+17);
8266     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8267
8268     if(caps.MaxPointSize >= 64.0) {
8269         color = getPixelColor(device, 256-33, 64-33);
8270         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8271         color = getPixelColor(device, 256-32, 64-32);
8272         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8273         color = getPixelColor(device, 256-31, 64-31);
8274         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8275         color = getPixelColor(device, 256+31, 64+31);
8276         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8277         color = getPixelColor(device, 256+32, 64+32);
8278         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8279         color = getPixelColor(device, 256+33, 64+33);
8280         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8281
8282         color = getPixelColor(device, 384-33, 64-33);
8283         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8284         color = getPixelColor(device, 384-32, 64-32);
8285         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8286         color = getPixelColor(device, 384-31, 64-31);
8287         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8288         color = getPixelColor(device, 384+31, 64+31);
8289         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8290         color = getPixelColor(device, 384+32, 64+32);
8291         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8292         color = getPixelColor(device, 384+33, 64+33);
8293         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8294     }
8295
8296     color = getPixelColor(device, 320-1, 64-1);
8297     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8298     color = getPixelColor(device, 320-0, 64-0);
8299     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8300     color = getPixelColor(device, 320+1, 64+1);
8301     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8302
8303     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8304     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8305     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8306     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8307 }
8308
8309 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8310 {
8311     HRESULT hr;
8312     IDirect3DPixelShader9 *ps;
8313     IDirect3DTexture9 *tex1, *tex2;
8314     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8315     D3DCAPS9 caps;
8316     DWORD color;
8317     DWORD shader_code[] = {
8318     0xffff0300,                                                             /* ps_3_0             */
8319     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8320     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8321     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8322     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8323     0x0000ffff                                                              /* END                */
8324     };
8325     float quad[] = {
8326        -1.0,   -1.0,    0.1,
8327         1.0,   -1.0,    0.1,
8328        -1.0,    1.0,    0.1,
8329         1.0,    1.0,    0.1,
8330     };
8331     float texquad[] = {
8332        -1.0,   -1.0,    0.1,    0.0,    0.0,
8333         0.0,   -1.0,    0.1,    1.0,    0.0,
8334        -1.0,    1.0,    0.1,    0.0,    1.0,
8335         0.0,    1.0,    0.1,    1.0,    1.0,
8336
8337         0.0,   -1.0,    0.1,    0.0,    0.0,
8338         1.0,   -1.0,    0.1,    1.0,    0.0,
8339         0.0,    1.0,    0.1,    0.0,    1.0,
8340         1.0,    1.0,    0.1,    1.0,    1.0,
8341     };
8342
8343     memset(&caps, 0, sizeof(caps));
8344     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8345     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8346     if(caps.NumSimultaneousRTs < 2) {
8347         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8348         return;
8349     }
8350
8351     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8352     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8353
8354     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8355     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8356     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8357     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8358     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8359     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8360
8361     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8362     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8363     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8364     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8365     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8366     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8367
8368     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8369     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8370     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8371     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8372     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8373     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8374     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8375     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8376
8377     hr = IDirect3DDevice9_BeginScene(device);
8378     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8379     if(SUCCEEDED(hr)) {
8380         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8381         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8382
8383         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8384         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8385         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8386         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8387         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8388         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8389         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8390         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8391
8392         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8393         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8395         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8396
8397         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8398         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8399         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8400         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8401
8402         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8403         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8404
8405         hr = IDirect3DDevice9_EndScene(device);
8406         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8407     }
8408
8409     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8410     color = getPixelColor(device, 160, 240);
8411     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8412     color = getPixelColor(device, 480, 240);
8413     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8414
8415     IDirect3DPixelShader9_Release(ps);
8416     IDirect3DTexture9_Release(tex1);
8417     IDirect3DTexture9_Release(tex2);
8418     IDirect3DSurface9_Release(surf1);
8419     IDirect3DSurface9_Release(surf2);
8420     IDirect3DSurface9_Release(backbuf);
8421 }
8422
8423 struct formats {
8424     const char *fmtName;
8425     D3DFORMAT textureFormat;
8426     DWORD resultColorBlending;
8427     DWORD resultColorNoBlending;
8428 };
8429
8430 const struct formats test_formats[] = {
8431   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8432   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8433   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8434   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8435   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8436   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8437   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8438   { NULL, 0 }
8439 };
8440
8441 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8442 {
8443     HRESULT hr;
8444     IDirect3DTexture9 *offscreenTexture = NULL;
8445     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8446     IDirect3D9 *d3d = NULL;
8447     DWORD color;
8448     DWORD r0, g0, b0, r1, g1, b1;
8449     int fmt_index;
8450
8451     static const float quad[][5] = {
8452         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8453         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8454         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8455         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8456     };
8457
8458     /* Quad with R=0x10, G=0x20 */
8459     static const struct vertex quad1[] = {
8460         {-1.0f, -1.0f, 0.1f, 0x80102000},
8461         {-1.0f,  1.0f, 0.1f, 0x80102000},
8462         { 1.0f, -1.0f, 0.1f, 0x80102000},
8463         { 1.0f,  1.0f, 0.1f, 0x80102000},
8464     };
8465
8466     /* Quad with R=0x20, G=0x10 */
8467     static const struct vertex quad2[] = {
8468         {-1.0f, -1.0f, 0.1f, 0x80201000},
8469         {-1.0f,  1.0f, 0.1f, 0x80201000},
8470         { 1.0f, -1.0f, 0.1f, 0x80201000},
8471         { 1.0f,  1.0f, 0.1f, 0x80201000},
8472     };
8473
8474     IDirect3DDevice9_GetDirect3D(device, &d3d);
8475
8476     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8477     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8478     if(!backbuffer) {
8479         goto out;
8480     }
8481
8482     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8483     {
8484         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8485         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8486            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8487            continue;
8488         }
8489
8490         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8491         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8492
8493         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8494         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8495         if(!offscreenTexture) {
8496             continue;
8497         }
8498
8499         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8500         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8501         if(!offscreen) {
8502             continue;
8503         }
8504
8505         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8506         ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8507
8508         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8509         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8510         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8511         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8512         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8513         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8514         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8515         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8516         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8517         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8518
8519         /* Below we will draw two quads with different colors and try to blend them together.
8520          * The result color is compared with the expected outcome.
8521          */
8522         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8523             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8524             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8525             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8526             ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8527
8528             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8529             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8530
8531             /* Draw a quad using color 0x0010200 */
8532             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8533             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8534             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8535             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8536             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8537             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8538
8539             /* Draw a quad using color 0x0020100 */
8540             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8541             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8542             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8543             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8544             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8545             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8546
8547             /* We don't want to blend the result on the backbuffer */
8548             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8549             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8550
8551             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8552             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8553             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8554             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8555             ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8556
8557             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8558             ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8559
8560             /* This time with the texture */
8561             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8562             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8563
8564             IDirect3DDevice9_EndScene(device);
8565         }
8566         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8567
8568
8569         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8570             /* Compare the color of the center quad with our expectation */
8571             color = getPixelColor(device, 320, 240);
8572             r0 = (color & 0x00ff0000) >> 16;
8573             g0 = (color & 0x0000ff00) >>  8;
8574             b0 = (color & 0x000000ff) >>  0;
8575
8576             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8577             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8578             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8579
8580             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8581                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8582                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8583                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8584         } else {
8585             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8586              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8587              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8588             color = getPixelColor(device, 320, 240);
8589             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);
8590         }
8591
8592         IDirect3DDevice9_SetTexture(device, 0, NULL);
8593         if(offscreenTexture) {
8594             IDirect3DTexture9_Release(offscreenTexture);
8595         }
8596         if(offscreen) {
8597             IDirect3DSurface9_Release(offscreen);
8598         }
8599     }
8600
8601 out:
8602     /* restore things */
8603     if(backbuffer) {
8604         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8605         IDirect3DSurface9_Release(backbuffer);
8606     }
8607 }
8608
8609 static void tssargtemp_test(IDirect3DDevice9 *device)
8610 {
8611     HRESULT hr;
8612     DWORD color;
8613     static const struct vertex quad[] = {
8614         {-1.0,     -1.0,    0.1,    0x00ff0000},
8615         { 1.0,     -1.0,    0.1,    0x00ff0000},
8616         {-1.0,      1.0,    0.1,    0x00ff0000},
8617         { 1.0,      1.0,    0.1,    0x00ff0000}
8618     };
8619     D3DCAPS9 caps;
8620
8621     memset(&caps, 0, sizeof(caps));
8622     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8623     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8624     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8625         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8626         return;
8627     }
8628
8629     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8630     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8631
8632     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8633     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8634     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8635     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8636
8637     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8638     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8639     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8640     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8641     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8642     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8643
8644     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8645     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8646     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8647     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8648     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8649     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8650
8651     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8652     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8653
8654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8655     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8656     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8657     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8658
8659     hr = IDirect3DDevice9_BeginScene(device);
8660     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8661     if(SUCCEEDED(hr)) {
8662
8663         hr = IDirect3DDevice9_EndScene(device);
8664         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8665         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8666         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8667     }
8668     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8669     color = getPixelColor(device, 320, 240);
8670     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8671
8672     /* Set stage 1 back to default */
8673     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8674     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8675     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8676     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8677     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8678     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8679     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8680     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8681     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8682     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8683 }
8684
8685 struct testdata
8686 {
8687     DWORD idxVertex; /* number of instances in the first stream */
8688     DWORD idxColor; /* number of instances in the second stream */
8689     DWORD idxInstance; /* should be 1 ?? */
8690     DWORD color1; /* color 1 instance */
8691     DWORD color2; /* color 2 instance */
8692     DWORD color3; /* color 3 instance */
8693     DWORD color4; /* color 4 instance */
8694     WORD strVertex; /* specify which stream to use 0-2*/
8695     WORD strColor;
8696     WORD strInstance;
8697 };
8698
8699 static const struct testdata testcases[]=
8700 {
8701     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8702     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8703     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8704     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8705     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8706     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8707     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8708     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8709     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8710     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8711     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8712     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8713     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8714     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8715     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8716 /*
8717     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8718     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8719 */
8720 };
8721
8722 /* Drawing Indexed Geometry with instances*/
8723 static void stream_test(IDirect3DDevice9 *device)
8724 {
8725     IDirect3DVertexBuffer9 *vb = NULL;
8726     IDirect3DVertexBuffer9 *vb2 = NULL;
8727     IDirect3DVertexBuffer9 *vb3 = NULL;
8728     IDirect3DIndexBuffer9 *ib = NULL;
8729     IDirect3DVertexDeclaration9 *pDecl = NULL;
8730     IDirect3DVertexShader9 *shader = NULL;
8731     HRESULT hr;
8732     BYTE *data;
8733     DWORD color;
8734     DWORD ind;
8735     int i;
8736
8737     const DWORD shader_code[] =
8738     {
8739         0xfffe0101,                                     /* vs_1_1 */
8740         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
8741         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
8742         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
8743         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
8744         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8745         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
8746         0x0000ffff
8747     };
8748
8749     const float quad[][3] =
8750     {
8751         {-0.5f, -0.5f,  1.1f}, /*0 */
8752         {-0.5f,  0.5f,  1.1f}, /*1 */
8753         { 0.5f, -0.5f,  1.1f}, /*2 */
8754         { 0.5f,  0.5f,  1.1f}, /*3 */
8755     };
8756
8757     const float vertcolor[][4] =
8758     {
8759         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8760         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8761         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8762         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8763     };
8764
8765     /* 4 position for 4 instances */
8766     const float instancepos[][3] =
8767     {
8768         {-0.6f,-0.6f, 0.0f},
8769         { 0.6f,-0.6f, 0.0f},
8770         { 0.6f, 0.6f, 0.0f},
8771         {-0.6f, 0.6f, 0.0f},
8772     };
8773
8774     short indices[] = {0, 1, 2, 1, 2, 3};
8775
8776     D3DVERTEXELEMENT9 decl[] =
8777     {
8778         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8779         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8780         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8781         D3DDECL_END()
8782     };
8783
8784     /* set the default value because it isn't done in wine? */
8785     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8786     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8787
8788     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8789     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8790     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8791
8792     /* check wrong cases */
8793     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8794     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8795     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8796     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8797     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8798     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8799     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8800     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8801     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8802     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8803     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8804     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8805     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8806     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8807     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8808     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8809     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8810     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8811     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8812     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8813
8814     /* set the default value back */
8815     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8816     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8817
8818     /* create all VertexBuffers*/
8819     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8820     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8821     if(!vb) {
8822         skip("Failed to create a vertex buffer\n");
8823         return;
8824     }
8825     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8826     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8827     if(!vb2) {
8828         skip("Failed to create a vertex buffer\n");
8829         goto out;
8830     }
8831     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8832     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8833     if(!vb3) {
8834         skip("Failed to create a vertex buffer\n");
8835         goto out;
8836     }
8837
8838     /* create IndexBuffer*/
8839     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8840     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8841     if(!ib) {
8842         skip("Failed to create a index buffer\n");
8843         goto out;
8844     }
8845
8846     /* copy all Buffers (Vertex + Index)*/
8847     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8848     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8849     memcpy(data, quad, sizeof(quad));
8850     hr = IDirect3DVertexBuffer9_Unlock(vb);
8851     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8852     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8853     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8854     memcpy(data, vertcolor, sizeof(vertcolor));
8855     hr = IDirect3DVertexBuffer9_Unlock(vb2);
8856     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8857     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8858     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8859     memcpy(data, instancepos, sizeof(instancepos));
8860     hr = IDirect3DVertexBuffer9_Unlock(vb3);
8861     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8862     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8863     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8864     memcpy(data, indices, sizeof(indices));
8865     hr = IDirect3DIndexBuffer9_Unlock(ib);
8866     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8867
8868     /* create VertexShader */
8869     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8870     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8871     if(!shader) {
8872         skip("Failed to create a vetex shader\n");
8873         goto out;
8874     }
8875
8876     hr = IDirect3DDevice9_SetVertexShader(device, shader);
8877     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8878
8879     hr = IDirect3DDevice9_SetIndices(device, ib);
8880     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8881
8882     /* run all tests */
8883     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8884     {
8885         struct testdata act = testcases[i];
8886         decl[0].Stream = act.strVertex;
8887         decl[1].Stream = act.strColor;
8888         decl[2].Stream = act.strInstance;
8889         /* create VertexDeclarations */
8890         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8891         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8892
8893         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8894         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8895
8896         hr = IDirect3DDevice9_BeginScene(device);
8897         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8898         if(SUCCEEDED(hr))
8899         {
8900             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8901             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8902
8903             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8904             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8905             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8906             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8907
8908             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8909             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8910             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8911             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8912
8913             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8914             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8915             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8916             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8917
8918             /* don't know if this is right (1*3 and 4*1)*/
8919             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8920             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8921             hr = IDirect3DDevice9_EndScene(device);
8922             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8923
8924             /* set all StreamSource && StreamSourceFreq back to default */
8925             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8926             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8927             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8928             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8929             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8930             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8931             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8932             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8933             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8934             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8935             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8936             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8937         }
8938
8939         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8940         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8941
8942         hr = IDirect3DVertexDeclaration9_Release(pDecl);
8943         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8944
8945         color = getPixelColor(device, 160, 360);
8946         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8947         color = getPixelColor(device, 480, 360);
8948         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8949         color = getPixelColor(device, 480, 120);
8950         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8951         color = getPixelColor(device, 160, 120);
8952         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8953     }
8954
8955     hr = IDirect3DDevice9_SetIndices(device, NULL);
8956     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8957
8958 out:
8959     if(vb) IDirect3DVertexBuffer9_Release(vb);
8960     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8961     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8962     if(ib)IDirect3DIndexBuffer9_Release(ib);
8963     if(shader)IDirect3DVertexShader9_Release(shader);
8964 }
8965
8966 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8967     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8968     IDirect3DTexture9 *dsttex = NULL;
8969     HRESULT hr;
8970     DWORD color;
8971     D3DRECT r1 = {0,  0,  50,  50 };
8972     D3DRECT r2 = {50, 0,  100, 50 };
8973     D3DRECT r3 = {50, 50, 100, 100};
8974     D3DRECT r4 = {0,  50,  50, 100};
8975     const float quad[] = {
8976         -1.0,   -1.0,   0.1,    0.0,    0.0,
8977          1.0,   -1.0,   0.1,    1.0,    0.0,
8978         -1.0,    1.0,   0.1,    0.0,    1.0,
8979          1.0,    1.0,   0.1,    1.0,    1.0,
8980     };
8981
8982     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8983     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
8984
8985     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
8986     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
8987     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
8988     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
8989
8990     if(!src || !dsttex) {
8991         skip("One or more test resources could not be created\n");
8992         goto cleanup;
8993     }
8994
8995     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
8996     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
8997
8998     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
8999     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9000
9001     /* Clear the StretchRect destination for debugging */
9002     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9003     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9004     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9005     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9006
9007     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9008     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9009
9010     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9012     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9013     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9014     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9015     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9016     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9017     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9018
9019     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9020      * the target -> texture GL blit path
9021      */
9022     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9024     IDirect3DSurface9_Release(dst);
9025
9026     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9027     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9028
9029     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9030     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9031     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9032     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9033     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9035     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9036     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9037
9038     hr = IDirect3DDevice9_BeginScene(device);
9039     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9040     if(SUCCEEDED(hr)) {
9041         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9042         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9043         hr = IDirect3DDevice9_EndScene(device);
9044         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9045     }
9046
9047     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9048     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9049     color = getPixelColor(device, 160, 360);
9050     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9051     color = getPixelColor(device, 480, 360);
9052     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9053     color = getPixelColor(device, 480, 120);
9054     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9055     color = getPixelColor(device, 160, 120);
9056     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9057
9058     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9059     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9060     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9061     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9062
9063 cleanup:
9064     if(src) IDirect3DSurface9_Release(src);
9065     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9066     if(dsttex) IDirect3DTexture9_Release(dsttex);
9067 }
9068
9069 START_TEST(visual)
9070 {
9071     IDirect3DDevice9 *device_ptr;
9072     D3DCAPS9 caps;
9073     HRESULT hr;
9074     DWORD color;
9075
9076     d3d9_handle = LoadLibraryA("d3d9.dll");
9077     if (!d3d9_handle)
9078     {
9079         skip("Could not load d3d9.dll\n");
9080         return;
9081     }
9082
9083     device_ptr = init_d3d9();
9084     if (!device_ptr)
9085     {
9086         skip("Creating the device failed\n");
9087         return;
9088     }
9089
9090     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9091
9092     /* Check for the reliability of the returned data */
9093     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9094     if(FAILED(hr))
9095     {
9096         trace("Clear failed, can't assure correctness of the test results, skipping\n");
9097         goto cleanup;
9098     }
9099     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9100
9101     color = getPixelColor(device_ptr, 1, 1);
9102     if(color !=0x00ff0000)
9103     {
9104         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9105         goto cleanup;
9106     }
9107
9108     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9109     if(FAILED(hr))
9110     {
9111         trace("Clear failed, can't assure correctness of the test results, skipping\n");
9112         goto cleanup;
9113     }
9114     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9115
9116     color = getPixelColor(device_ptr, 639, 479);
9117     if(color != 0x0000ddee)
9118     {
9119         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9120         goto cleanup;
9121     }
9122
9123     /* Now execute the real tests */
9124     stretchrect_test(device_ptr);
9125     lighting_test(device_ptr);
9126     clear_test(device_ptr);
9127     fog_test(device_ptr);
9128     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9129     {
9130         test_cube_wrap(device_ptr);
9131     } else {
9132         skip("No cube texture support\n");
9133     }
9134     z_range_test(device_ptr);
9135     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9136     {
9137         maxmip_test(device_ptr);
9138     }
9139     else
9140     {
9141         skip("No mipmap support\n");
9142     }
9143     offscreen_test(device_ptr);
9144     alpha_test(device_ptr);
9145     shademode_test(device_ptr);
9146     srgbtexture_test(device_ptr);
9147     release_buffer_test(device_ptr);
9148     float_texture_test(device_ptr);
9149     g16r16_texture_test(device_ptr);
9150     pixelshader_blending_test(device_ptr);
9151     texture_transform_flags_test(device_ptr);
9152     autogen_mipmap_test(device_ptr);
9153     fixed_function_decl_test(device_ptr);
9154     conditional_np2_repeat_test(device_ptr);
9155     fixed_function_bumpmap_test(device_ptr);
9156     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9157         stencil_cull_test(device_ptr);
9158     } else {
9159         skip("No two sided stencil support\n");
9160     }
9161     pointsize_test(device_ptr);
9162     tssargtemp_test(device_ptr);
9163     np2_stretch_rect_test(device_ptr);
9164
9165     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9166     {
9167         test_constant_clamp_vs(device_ptr);
9168         test_compare_instructions(device_ptr);
9169     }
9170     else skip("No vs_1_1 support\n");
9171
9172     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9173     {
9174         test_mova(device_ptr);
9175         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9176             test_vshader_input(device_ptr);
9177             test_vshader_float16(device_ptr);
9178             stream_test(device_ptr);
9179         } else {
9180             skip("No vs_3_0 support\n");
9181         }
9182     }
9183     else skip("No vs_2_0 support\n");
9184
9185     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9186     {
9187         fog_with_shader_test(device_ptr);
9188         fog_srgbwrite_test(device_ptr);
9189     }
9190     else skip("No vs_1_1 and ps_1_1 support\n");
9191
9192     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9193     {
9194         texbem_test(device_ptr);
9195         texdepth_test(device_ptr);
9196         texkill_test(device_ptr);
9197         x8l8v8u8_test(device_ptr);
9198         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9199             constant_clamp_ps_test(device_ptr);
9200             cnd_test(device_ptr);
9201             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9202                 dp2add_ps_test(device_ptr);
9203                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9204                     nested_loop_test(device_ptr);
9205                     fixed_function_varying_test(device_ptr);
9206                     vFace_register_test(device_ptr);
9207                     vpos_register_test(device_ptr);
9208                     multiple_rendertargets_test(device_ptr);
9209                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9210                         vshader_version_varying_test(device_ptr);
9211                         pshader_version_varying_test(device_ptr);
9212                     } else {
9213                         skip("No vs_3_0 support\n");
9214                     }
9215                 } else {
9216                     skip("No ps_3_0 support\n");
9217                 }
9218             } else {
9219                 skip("No ps_2_0 support\n");
9220             }
9221         }
9222     }
9223     else skip("No ps_1_1 support\n");
9224
9225 cleanup:
9226     if(device_ptr) {
9227         ULONG ref;
9228
9229         D3DPRESENT_PARAMETERS present_parameters;
9230         IDirect3DSwapChain9 *swapchain;
9231         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9232         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9233         IDirect3DSwapChain9_Release(swapchain);
9234         ref = IDirect3DDevice9_Release(device_ptr);
9235         DestroyWindow(present_parameters.hDeviceWindow);
9236         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
9237     }
9238 }