d3d9/tests: Fix compilation on systems that don't support nameless unions.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007 Henri Verbeet
3  * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include <dxerr9.h>
34 #include "wine/test.h"
35
36 static HMODULE d3d9_handle = 0;
37
38 static HWND create_window(void)
39 {
40     WNDCLASS wc = {0};
41     HWND ret;
42     wc.lpfnWndProc = &DefWindowProc;
43     wc.lpszClassName = "d3d9_test_wc";
44     RegisterClass(&wc);
45
46     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
47                         WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
48     return ret;
49 }
50
51 /* Locks a given surface and returns the color at (x,y).  It's the caller's
52  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
53 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
54 {
55     DWORD color;
56     HRESULT hr;
57     D3DSURFACE_DESC desc;
58     RECT rectToLock = {x, y, x+1, y+1};
59     D3DLOCKED_RECT lockedRect;
60
61     hr = IDirect3DSurface9_GetDesc(surface, &desc);
62     if(FAILED(hr))  /* This is not a test */
63     {
64         trace("Can't get the surface description, hr=%s\n", DXGetErrorString9(hr));
65         return 0xdeadbeef;
66     }
67
68     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
69     if(FAILED(hr))  /* This is not a test */
70     {
71         trace("Can't lock the surface, hr=%s\n", DXGetErrorString9(hr));
72         return 0xdeadbeef;
73     }
74     switch(desc.Format) {
75         case D3DFMT_A8R8G8B8:
76         {
77             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
78             break;
79         }
80         default:
81             trace("Error: unknown surface format: %d\n", desc.Format);
82             color = 0xdeadbeef;
83             break;
84     }
85     hr = IDirect3DSurface9_UnlockRect(surface);
86     if(FAILED(hr))
87     {
88         trace("Can't unlock the surface, hr=%s\n", DXGetErrorString9(hr));
89     }
90     return color;
91 }
92
93 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
94 {
95     DWORD ret;
96     IDirect3DSurface9 *surf;
97     HRESULT hr;
98     D3DLOCKED_RECT lockedRect;
99     RECT rectToLock = {x, y, x+1, y+1};
100
101     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
102     if(FAILED(hr) || !surf )  /* This is not a test */
103     {
104         trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
105         return 0xdeadbeef;
106     }
107
108     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
109     if(FAILED(hr))
110     {
111         trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
112         ret = 0xdeadbeed;
113         goto out;
114     }
115
116     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
117     if(FAILED(hr))
118     {
119         trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
120         ret = 0xdeadbeec;
121         goto out;
122     }
123
124     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
125      * really important for these tests
126      */
127     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
128     hr = IDirect3DSurface9_UnlockRect(surf);
129     if(FAILED(hr))
130     {
131         trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
132     }
133
134 out:
135     if(surf) IDirect3DSurface9_Release(surf);
136     return ret;
137 }
138
139 static IDirect3DDevice9 *init_d3d9(void)
140 {
141     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
142     IDirect3D9 *d3d9_ptr = 0;
143     IDirect3DDevice9 *device_ptr = 0;
144     D3DPRESENT_PARAMETERS present_parameters;
145     HRESULT hr;
146     D3DADAPTER_IDENTIFIER9 identifier;
147
148     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
149     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
150     if (!d3d9_create) return NULL;
151
152     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
153     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
154     if (!d3d9_ptr) return NULL;
155
156     ZeroMemory(&present_parameters, sizeof(present_parameters));
157     present_parameters.Windowed = FALSE;
158     present_parameters.hDeviceWindow = create_window();
159     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
160     present_parameters.BackBufferWidth = 640;
161     present_parameters.BackBufferHeight = 480;
162     present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
163     present_parameters.EnableAutoDepthStencil = TRUE;
164     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
165
166     memset(&identifier, 0, sizeof(identifier));
167     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
168     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
169     trace("Driver string: \"%s\"\n", identifier.Driver);
170     trace("Description string: \"%s\"\n", identifier.Description);
171     trace("Device name string: \"%s\"\n", identifier.DeviceName);
172     trace("Driver version %d.%d.%d.%d\n",
173           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
174           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
175
176     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
177     if(FAILED(hr)) {
178         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
179         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
180         if(FAILED(hr)) {
181             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
182         }
183     }
184     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
185
186     return device_ptr;
187 }
188
189 struct vertex
190 {
191     float x, y, z;
192     DWORD diffuse;
193 };
194
195 struct tvertex
196 {
197     float x, y, z, rhw;
198     DWORD diffuse;
199 };
200
201 struct nvertex
202 {
203     float x, y, z;
204     float nx, ny, nz;
205     DWORD diffuse;
206 };
207
208 static void lighting_test(IDirect3DDevice9 *device)
209 {
210     HRESULT hr;
211     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
212     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
213     DWORD color;
214
215     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
216                       0.0f, 1.0f, 0.0f, 0.0f,
217                       0.0f, 0.0f, 1.0f, 0.0f,
218                       0.0f, 0.0f, 0.0f, 1.0f };
219
220     struct vertex unlitquad[] =
221     {
222         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
223         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
224         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
225         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
226     };
227     struct vertex litquad[] =
228     {
229         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
230         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
231         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
232         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
233     };
234     struct nvertex unlitnquad[] =
235     {
236         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
237         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
238         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
239         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
240     };
241     struct nvertex litnquad[] =
242     {
243         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
244         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
245         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
246         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
247     };
248     WORD Indices[] = {0, 1, 2, 2, 3, 0};
249
250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
252
253     /* Setup some states that may cause issues */
254     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
255     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
256     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
257     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
258     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
259     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
260     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
261     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
262     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
263     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
264     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
265     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
266     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
267     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
274     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
275     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
276     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
277     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
278
279     hr = IDirect3DDevice9_SetFVF(device, fvf);
280     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
281
282     hr = IDirect3DDevice9_BeginScene(device);
283     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
284     if(hr == D3D_OK)
285     {
286         /* No lights are defined... That means, lit vertices should be entirely black */
287         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
288         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
289         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
290                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
291         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
292
293         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
294         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
295         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
296                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
297         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
298
299         hr = IDirect3DDevice9_SetFVF(device, nfvf);
300         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
301
302         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
303         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
304         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
305                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
306         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
307
308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
310         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
311                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
312         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
313
314         IDirect3DDevice9_EndScene(device);
315         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
316     }
317
318     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
319
320     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
321     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
322     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
323     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
324     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
325     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
326     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
327     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
328
329     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
330     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
331 }
332
333 static void clear_test(IDirect3DDevice9 *device)
334 {
335     /* Tests the correctness of clearing parameters */
336     HRESULT hr;
337     D3DRECT rect[2];
338     D3DRECT rect_negneg;
339     DWORD color;
340     D3DVIEWPORT9 old_vp, vp;
341     RECT scissor;
342     DWORD oldColorWrite;
343     BOOL invalid_clear_failed = FALSE;
344
345     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
346     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
347
348     /* Positive x, negative y */
349     rect[0].x1 = 0;
350     rect[0].y1 = 480;
351     rect[0].x2 = 320;
352     rect[0].y2 = 240;
353
354     /* Positive x, positive y */
355     rect[1].x1 = 0;
356     rect[1].y1 = 0;
357     rect[1].x2 = 320;
358     rect[1].y2 = 240;
359     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
360      * returns D3D_OK, but ignores the rectangle silently
361      */
362     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
363     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
364     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
365
366     /* negative x, negative y */
367     rect_negneg.x1 = 640;
368     rect_negneg.y1 = 240;
369     rect_negneg.x2 = 320;
370     rect_negneg.y2 = 0;
371     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
372     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
373     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
374
375     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
376
377     color = getPixelColor(device, 160, 360); /* lower left quad */
378     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
379     color = getPixelColor(device, 160, 120); /* upper left quad */
380     if(invalid_clear_failed) {
381         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
382         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
383     } else {
384         /* If the negative rectangle was dropped silently, the correct ones are cleared */
385         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
386     }
387     color = getPixelColor(device, 480, 360); /* lower right quad  */
388     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
389     color = getPixelColor(device, 480, 120); /* upper right quad */
390     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
391
392     /* Test how the viewport affects clears */
393     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
394     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
395     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
396     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
397
398     vp.X = 160;
399     vp.Y = 120;
400     vp.Width = 160;
401     vp.Height = 120;
402     vp.MinZ = 0.0;
403     vp.MaxZ = 1.0;
404     hr = IDirect3DDevice9_SetViewport(device, &vp);
405     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
406     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
407     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
408
409     vp.X = 320;
410     vp.Y = 240;
411     vp.Width = 320;
412     vp.Height = 240;
413     vp.MinZ = 0.0;
414     vp.MaxZ = 1.0;
415     hr = IDirect3DDevice9_SetViewport(device, &vp);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
417     rect[0].x1 = 160;
418     rect[0].y1 = 120;
419     rect[0].x2 = 480;
420     rect[0].y2 = 360;
421     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
422     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
423
424     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
425     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
426
427     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
428     color = getPixelColor(device, 158, 118);
429     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
430     color = getPixelColor(device, 162, 118);
431     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
432     color = getPixelColor(device, 158, 122);
433     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
434     color = getPixelColor(device, 162, 122);
435     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
436
437     color = getPixelColor(device, 318, 238);
438     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
439     color = getPixelColor(device, 322, 238);
440     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
441     color = getPixelColor(device, 318, 242);
442     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
443     color = getPixelColor(device, 322, 242);
444     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
445
446     color = getPixelColor(device, 478, 358);
447     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
448     color = getPixelColor(device, 482, 358);
449     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
450     color = getPixelColor(device, 478, 362);
451     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
452     color = getPixelColor(device, 482, 362);
453     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
454
455     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
456     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
457
458     scissor.left = 160;
459     scissor.right = 480;
460     scissor.top = 120;
461     scissor.bottom = 360;
462     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
463     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
464     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
465     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
466
467     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
468     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
469     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
470     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
471
472     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
473     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
474
475     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
476     color = getPixelColor(device, 158, 118);
477     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
478     color = getPixelColor(device, 162, 118);
479     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
480     color = getPixelColor(device, 158, 122);
481     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
482     color = getPixelColor(device, 162, 122);
483     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
484
485     color = getPixelColor(device, 158, 358);
486     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
487     color = getPixelColor(device, 162, 358);
488     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
489     color = getPixelColor(device, 158, 358);
490     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
491     color = getPixelColor(device, 162, 362);
492     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
493
494     color = getPixelColor(device, 478, 118);
495     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
496     color = getPixelColor(device, 478, 122);
497     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
498     color = getPixelColor(device, 482, 122);
499     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
500     color = getPixelColor(device, 482, 358);
501     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
502
503     color = getPixelColor(device, 478, 358);
504     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
505     color = getPixelColor(device, 478, 362);
506     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
507     color = getPixelColor(device, 482, 358);
508     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
509     color = getPixelColor(device, 482, 362);
510     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
511
512     color = getPixelColor(device, 318, 238);
513     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
514     color = getPixelColor(device, 318, 242);
515     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
516     color = getPixelColor(device, 322, 238);
517     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
518     color = getPixelColor(device, 322, 242);
519     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
520
521     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
522     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
523     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
524     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
525
526     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
527     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
528
529     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
530     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
531
532     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
533
534     /* Colorwriteenable does not affect the clear */
535     color = getPixelColor(device, 320, 240);
536     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
537 }
538
539 typedef struct {
540     float in[4];
541     DWORD out;
542 } test_data_t;
543
544 /*
545  *  c7      mova    ARGB            mov     ARGB
546  * -2.4     -2      0x00ffff00      -3      0x00ff0000
547  * -1.6     -2      0x00ffff00      -2      0x00ffff00
548  * -0.4      0      0x0000ffff      -1      0x0000ff00
549  *  0.4      0      0x0000ffff       0      0x0000ffff
550  *  1.6      2      0x00ff00ff       1      0x000000ff
551  *  2.4      2      0x00ff00ff       2      0x00ff00ff
552  */
553 static void test_mova(IDirect3DDevice9 *device)
554 {
555     static const DWORD mova_test[] = {
556         0xfffe0200,                                                             /* vs_2_0                       */
557         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
558         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
559         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
560         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
561         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
562         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
563         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
564         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
565         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
566         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
567         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
568         0x0000ffff                                                              /* END                          */
569     };
570     static const DWORD mov_test[] = {
571         0xfffe0101,                                                             /* vs_1_1                       */
572         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
573         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
574         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
575         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
576         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
577         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
578         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
579         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
580         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
581         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
582         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
583         0x0000ffff                                                              /* END                          */
584     };
585
586     static const test_data_t test_data[2][6] = {
587         {
588             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
589             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
590             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
591             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
592             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
593             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
594         },
595         {
596             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
597             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
598             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
599             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
600             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
601             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
602         }
603     };
604
605     static const float quad[][3] = {
606         {-1.0f, -1.0f, 0.0f},
607         {-1.0f,  1.0f, 0.0f},
608         { 1.0f, -1.0f, 0.0f},
609         { 1.0f,  1.0f, 0.0f},
610     };
611
612     static const D3DVERTEXELEMENT9 decl_elements[] = {
613         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
614         D3DDECL_END()
615     };
616
617     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
618     IDirect3DVertexShader9 *mova_shader = NULL;
619     IDirect3DVertexShader9 *mov_shader = NULL;
620     HRESULT hr;
621     UINT i, j;
622
623     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
624     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
625     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
626     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
627     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
628     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
629     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
630     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
631
632     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
633     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
634     for(j = 0; j < 2; ++j)
635     {
636         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
637         {
638             DWORD color;
639
640             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
641             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
642
643             hr = IDirect3DDevice9_BeginScene(device);
644             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
645
646             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
647             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
648
649             hr = IDirect3DDevice9_EndScene(device);
650             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
651
652             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
653             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
654
655             color = getPixelColor(device, 320, 240);
656             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
657                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
658
659             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
660             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
661         }
662         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
663         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
664     }
665
666     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
667     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
668
669     IDirect3DVertexDeclaration9_Release(vertex_declaration);
670     IDirect3DVertexShader9_Release(mova_shader);
671     IDirect3DVertexShader9_Release(mov_shader);
672 }
673
674 struct sVertex {
675     float x, y, z;
676     DWORD diffuse;
677     DWORD specular;
678 };
679
680 struct sVertexT {
681     float x, y, z, rhw;
682     DWORD diffuse;
683     DWORD specular;
684 };
685
686 static void fog_test(IDirect3DDevice9 *device)
687 {
688     HRESULT hr;
689     DWORD color;
690     BYTE r, g, b;
691     float start = 0.0f, end = 1.0f;
692     D3DCAPS9 caps;
693     int i;
694
695     /* Gets full z based fog with linear fog, no fog with specular color */
696     struct sVertex unstransformed_1[] = {
697         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
698         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
699         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
700         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
701     };
702     /* Ok, I am too lazy to deal with transform matrices */
703     struct sVertex unstransformed_2[] = {
704         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
705         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
706         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
707         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
708     };
709     /* Untransformed ones. Give them a different diffuse color to make the test look
710      * nicer. It also makes making sure that they are drawn correctly easier.
711      */
712     struct sVertexT transformed_1[] = {
713         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
714         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
715         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
716         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
717     };
718     struct sVertexT transformed_2[] = {
719         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
720         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
721         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
722         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
723     };
724     struct vertex rev_fog_quads[] = {
725        {-1.0,   -1.0,   0.1,    0x000000ff},
726        {-1.0,    0.0,   0.1,    0x000000ff},
727        { 0.0,    0.0,   0.1,    0x000000ff},
728        { 0.0,   -1.0,   0.1,    0x000000ff},
729
730        { 0.0,   -1.0,   0.9,    0x000000ff},
731        { 0.0,    0.0,   0.9,    0x000000ff},
732        { 1.0,    0.0,   0.9,    0x000000ff},
733        { 1.0,   -1.0,   0.9,    0x000000ff},
734
735        { 0.0,    0.0,   0.4,    0x000000ff},
736        { 0.0,    1.0,   0.4,    0x000000ff},
737        { 1.0,    1.0,   0.4,    0x000000ff},
738        { 1.0,    0.0,   0.4,    0x000000ff},
739
740        {-1.0,    0.0,   0.7,    0x000000ff},
741        {-1.0,    1.0,   0.7,    0x000000ff},
742        { 0.0,    1.0,   0.7,    0x000000ff},
743        { 0.0,    0.0,   0.7,    0x000000ff},
744     };
745     WORD Indices[] = {0, 1, 2, 2, 3, 0};
746
747     memset(&caps, 0, sizeof(caps));
748     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
749     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
750     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
751     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
752
753     /* Setup initial states: No lighting, fog on, fog color */
754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
755     ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
757     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
759     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
760
761     /* First test: Both table fog and vertex fog off */
762     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
763     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
764     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
765     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
766
767     /* Start = 0, end = 1. Should be default, but set them */
768     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
769     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
770     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
771     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
772
773     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
774     {
775         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
776         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
777         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
778         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
779                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
780                                                      sizeof(unstransformed_1[0]));
781         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
782
783         /* That makes it use the Z value */
784         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
785         ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
786         /* Untransformed, vertex fog != none (or table fog != none):
787          * Use the Z value as input into the equation
788          */
789         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
790                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
791                                                      sizeof(unstransformed_1[0]));
792         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
793
794         /* transformed verts */
795         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
796         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
797         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
798         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
799                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
800                                                      sizeof(transformed_1[0]));
801         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
802
803         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
804         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
805         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
806          * equation
807          */
808         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
809                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
810                                                      sizeof(transformed_2[0]));
811
812         hr = IDirect3DDevice9_EndScene(device);
813         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
814     }
815     else
816     {
817         ok(FALSE, "BeginScene failed\n");
818     }
819
820     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
821     color = getPixelColor(device, 160, 360);
822     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
823     color = getPixelColor(device, 160, 120);
824     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
825     color = getPixelColor(device, 480, 120);
826     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
827     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
828     {
829         color = getPixelColor(device, 480, 360);
830         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
831     }
832     else
833     {
834         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
835          * The settings above result in no fogging with vertex fog
836          */
837         color = getPixelColor(device, 480, 120);
838         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
839         trace("Info: Table fog not supported by this device\n");
840     }
841
842     /* Now test the special case fogstart == fogend */
843     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
844     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
845
846     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
847     {
848         start = 512;
849         end = 512;
850         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
851         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
852         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
853         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
854
855         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
856         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
857         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
858         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
859         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
860         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
861
862         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
863          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
864          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
865          * The third transformed quad remains unfogged because the fogcoords are read from the specular
866          * color and has fixed fogstart and fogend.
867          */
868         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
869                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
870                 sizeof(unstransformed_1[0]));
871         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
872         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
873                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
874                 sizeof(unstransformed_1[0]));
875         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
876
877         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
878         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
879         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
880         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
881                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
882                 sizeof(transformed_1[0]));
883         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
884
885         hr = IDirect3DDevice9_EndScene(device);
886         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
887     }
888     else
889     {
890         ok(FALSE, "BeginScene failed\n");
891     }
892     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
893     color = getPixelColor(device, 160, 360);
894     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
895     color = getPixelColor(device, 160, 120);
896     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
897     color = getPixelColor(device, 480, 120);
898     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
899
900     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
901      * but without shaders it seems to work everywhere
902      */
903     end = 0.2;
904     start = 0.8;
905     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
906     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
908     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
910     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
911
912     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
913      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
914      * so skip this for now
915      */
916     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
917         const char *mode = (i ? "table" : "vertex");
918         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
919         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
920         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
921         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
922         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
923         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
924         hr = IDirect3DDevice9_BeginScene(device);
925         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
926         if(SUCCEEDED(hr)) {
927             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
928                                 4,  5,  6,  6,  7, 4,
929                                 8,  9, 10, 10, 11, 8,
930                             12, 13, 14, 14, 15, 12};
931
932             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
933                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
934                     sizeof(rev_fog_quads[0]));
935
936             hr = IDirect3DDevice9_EndScene(device);
937             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
938         }
939         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
940         color = getPixelColor(device, 160, 360);
941         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
942
943         color = getPixelColor(device, 160, 120);
944         r = (color & 0x00ff0000) >> 16;
945         g = (color & 0x0000ff00) >>  8;
946         b = (color & 0x000000ff);
947         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
948            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
949
950         color = getPixelColor(device, 480, 120);
951         r = (color & 0x00ff0000) >> 16;
952         g = (color & 0x0000ff00) >>  8;
953         b = (color & 0x000000ff);
954         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
955            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
956
957         color = getPixelColor(device, 480, 360);
958         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
959
960         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
961             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
962             break;
963         }
964     }
965     /* Turn off the fog master switch to avoid confusing other tests */
966     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
967     ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
968     start = 0.0;
969     end = 1.0;
970     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
971     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
972     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
973     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
974     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
975     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
976     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
977     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
978 }
979
980 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
981  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
982  * regardless of the actual addressing mode set. */
983 static void test_cube_wrap(IDirect3DDevice9 *device)
984 {
985     static const float quad[][6] = {
986         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
987         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
988         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
989         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
990     };
991
992     static const D3DVERTEXELEMENT9 decl_elements[] = {
993         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
994         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
995         D3DDECL_END()
996     };
997
998     static const struct {
999         D3DTEXTUREADDRESS mode;
1000         const char *name;
1001     } address_modes[] = {
1002         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1003         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1004         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1005         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1006         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1007     };
1008
1009     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1010     IDirect3DCubeTexture9 *texture = NULL;
1011     IDirect3DSurface9 *surface = NULL;
1012     D3DLOCKED_RECT locked_rect;
1013     HRESULT hr;
1014     UINT x;
1015     INT y, face;
1016
1017     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1018     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1019     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1020     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1021
1022     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1023             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1024     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1025
1026     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1027     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1028
1029     for (y = 0; y < 128; ++y)
1030     {
1031         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1032         for (x = 0; x < 64; ++x)
1033         {
1034             *ptr++ = 0xffff0000;
1035         }
1036         for (x = 64; x < 128; ++x)
1037         {
1038             *ptr++ = 0xff0000ff;
1039         }
1040     }
1041
1042     hr = IDirect3DSurface9_UnlockRect(surface);
1043     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1044
1045     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1046             D3DPOOL_DEFAULT, &texture, NULL);
1047     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1048
1049     /* Create cube faces */
1050     for (face = 0; face < 6; ++face)
1051     {
1052         IDirect3DSurface9 *face_surface = NULL;
1053
1054         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1055         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1056
1057         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1058         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1059
1060         IDirect3DSurface9_Release(face_surface);
1061     }
1062
1063     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1064     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1065
1066     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1067     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1068     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1069     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1070     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1071     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1072
1073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1074     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1075
1076     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1077     {
1078         DWORD color;
1079
1080         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1081         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1082         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1083         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1084
1085         hr = IDirect3DDevice9_BeginScene(device);
1086         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1087
1088         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1089         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1090
1091         hr = IDirect3DDevice9_EndScene(device);
1092         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1093
1094         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1095         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1096
1097         /* Due to the nature of this test, we sample essentially at the edge
1098          * between two faces. Because of this it's undefined from which face
1099          * the driver will sample. Fortunately that's not important for this
1100          * test, since all we care about is that it doesn't sample from the
1101          * other side of the surface or from the border. */
1102         color = getPixelColor(device, 320, 240);
1103         ok(color == 0x00ff0000 || color == 0x000000ff,
1104                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1105                 color, address_modes[x].name);
1106
1107         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1108         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1109     }
1110
1111     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1112     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1113
1114     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1115     IDirect3DCubeTexture9_Release(texture);
1116     IDirect3DSurface9_Release(surface);
1117 }
1118
1119 static void offscreen_test(IDirect3DDevice9 *device)
1120 {
1121     HRESULT hr;
1122     IDirect3DTexture9 *offscreenTexture = NULL;
1123     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1124     DWORD color;
1125
1126     static const float quad[][5] = {
1127         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1128         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1129         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1130         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1131     };
1132
1133     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1134     ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1135
1136     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1137     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1138     if(!offscreenTexture) {
1139         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1140         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1141         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1142         if(!offscreenTexture) {
1143             skip("Cannot create an offscreen render target\n");
1144             goto out;
1145         }
1146     }
1147
1148     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1149     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1150     if(!backbuffer) {
1151         goto out;
1152     }
1153
1154     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1155     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1156     if(!offscreen) {
1157         goto out;
1158     }
1159
1160     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1161     ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1162
1163     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1164     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1165     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1166     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1167     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1168     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1169     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1170     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1171     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1172     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1173
1174     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1175         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1176         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1177         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1178         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1179
1180         /* Draw without textures - Should result in a white quad */
1181         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1182         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1183
1184         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1185         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1186         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1187         ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1188
1189         /* This time with the texture */
1190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1191         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1192
1193         IDirect3DDevice9_EndScene(device);
1194     }
1195
1196     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1197
1198     /* Center quad - should be white */
1199     color = getPixelColor(device, 320, 240);
1200     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1201     /* Some quad in the cleared part of the texture */
1202     color = getPixelColor(device, 170, 240);
1203     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1204     /* Part of the originally cleared back buffer */
1205     color = getPixelColor(device, 10, 10);
1206     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1207     if(0) {
1208         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1209          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1210          * the offscreen rendering mode this test would succeed or fail
1211          */
1212         color = getPixelColor(device, 10, 470);
1213         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1214     }
1215
1216 out:
1217     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1218
1219     /* restore things */
1220     if(backbuffer) {
1221         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1222         IDirect3DSurface9_Release(backbuffer);
1223     }
1224     if(offscreenTexture) {
1225         IDirect3DTexture9_Release(offscreenTexture);
1226     }
1227     if(offscreen) {
1228         IDirect3DSurface9_Release(offscreen);
1229     }
1230 }
1231
1232 /* This test tests fog in combination with shaders.
1233  * What's tested: linear fog (vertex and table) with pixel shader
1234  *                linear table fog with non foggy vertex shader
1235  *                vertex fog with foggy vertex shader
1236  * What's not tested: non linear fog with shader
1237  *                    table fog with foggy vertex shader
1238  */
1239 static void fog_with_shader_test(IDirect3DDevice9 *device)
1240 {
1241     HRESULT hr;
1242     DWORD color;
1243     union {
1244         float f;
1245         DWORD i;
1246     } start, end;
1247     unsigned int i, j;
1248
1249     /* basic vertex shader without fog computation ("non foggy") */
1250     static const DWORD vertex_shader_code1[] = {
1251         0xfffe0101,                                                             /* vs_1_1                       */
1252         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1253         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1254         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1255         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1256         0x0000ffff
1257     };
1258     /* basic vertex shader with reversed fog computation ("foggy") */
1259     static const DWORD vertex_shader_code2[] = {
1260         0xfffe0101,                                                             /* vs_1_1                        */
1261         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1262         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1263         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1264         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1265         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1266         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1267         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1268         0x0000ffff
1269     };
1270     /* basic pixel shader */
1271     static const DWORD pixel_shader_code[] = {
1272         0xffff0101,                                                             /* ps_1_1     */
1273         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1274         0x0000ffff
1275     };
1276
1277     static struct vertex quad[] = {
1278         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1279         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1280         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1281         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1282     };
1283
1284     static const D3DVERTEXELEMENT9 decl_elements[] = {
1285         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1286         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1287         D3DDECL_END()
1288     };
1289
1290     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1291     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1292     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1293
1294     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1295     static const struct test_data_t {
1296         int vshader;
1297         int pshader;
1298         D3DFOGMODE vfog;
1299         D3DFOGMODE tfog;
1300         unsigned int color[11];
1301     } test_data[] = {
1302         /* only pixel shader: */
1303         {0, 1, 0, 3,
1304         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1305         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1306         {0, 1, 1, 3,
1307         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1308         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1309         {0, 1, 2, 3,
1310         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1311         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1312         {0, 1, 3, 0,
1313         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1314         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1315         {0, 1, 3, 3,
1316         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1317         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1318
1319         /* vertex shader */
1320         {1, 0, 0, 0,
1321         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1322          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1323         {1, 0, 0, 3,
1324         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1325         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1326         {1, 0, 1, 3,
1327         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1328         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1329
1330         {1, 0, 2, 3,
1331         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1332         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1333         {1, 0, 3, 3,
1334         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1335         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1336
1337         /* vertex shader and pixel shader */
1338         {1, 1, 0, 3,
1339         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1340         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1341         {1, 1, 1, 3,
1342         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1343         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1344         {1, 1, 2, 3,
1345         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1346         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1347
1348         {1, 1, 3, 3,
1349         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1350         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1351
1352
1353 #if 0  /* FIXME: these fail on GeForce 8500 */
1354         /* foggy vertex shader */
1355         {2, 0, 0, 0,
1356         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1357          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1358         {2, 0, 1, 0,
1359         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1360          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1361         {2, 0, 2, 0,
1362         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1363          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1364         {2, 0, 3, 0,
1365         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1366          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1367 #endif
1368
1369         /* foggy vertex shader and pixel shader */
1370         {2, 1, 0, 0,
1371         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1372          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1373         {2, 1, 1, 0,
1374         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1375          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1376         {2, 1, 2, 0,
1377         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1378          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1379         {2, 1, 3, 0,
1380         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1381          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1382
1383     };
1384
1385     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1386     start.f=0.1f;
1387     end.f=0.9f;
1388
1389     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1390     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1391     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1392     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1393     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1394     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1395     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1396     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1397
1398     /* Setup initial states: No lighting, fog on, fog color */
1399     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1400     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1401     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1402     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1403     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1404     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1405     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1406     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1407
1408     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1409     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1410     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1411     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1412
1413     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1415     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1417     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1418
1419     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1420     {
1421         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1422         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1423         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1424         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1425         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1426         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1427         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1428         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1429
1430         for(j=0; j < 11; j++)
1431         {
1432             /* Don't use the whole zrange to prevent rounding errors */
1433             quad[0].z = 0.001f + (float)j / 10.02f;
1434             quad[1].z = 0.001f + (float)j / 10.02f;
1435             quad[2].z = 0.001f + (float)j / 10.02f;
1436             quad[3].z = 0.001f + (float)j / 10.02f;
1437
1438             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1439             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1440
1441             hr = IDirect3DDevice9_BeginScene(device);
1442             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1443
1444             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1445             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1446
1447             hr = IDirect3DDevice9_EndScene(device);
1448             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1449
1450             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1451
1452             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1453             color = getPixelColor(device, 128, 240);
1454             ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1455                     && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1456                     && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1457                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1458                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1459         }
1460     }
1461
1462     /* reset states */
1463     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1464     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1465     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1466     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1467     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1468     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1469     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1470     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1471
1472     IDirect3DVertexShader9_Release(vertex_shader[1]);
1473     IDirect3DVertexShader9_Release(vertex_shader[2]);
1474     IDirect3DPixelShader9_Release(pixel_shader[1]);
1475     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1476 }
1477
1478 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1479     unsigned int i, x, y;
1480     HRESULT hr;
1481     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1482     D3DLOCKED_RECT locked_rect;
1483
1484     /* Generate the textures */
1485     for(i=0; i<2; i++)
1486     {
1487         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1488                                             D3DPOOL_MANAGED, &texture[i], NULL);
1489         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1490
1491         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1492         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1493         for (y = 0; y < 128; ++y)
1494         {
1495             if(i)
1496             { /* Set up black texture with 2x2 texel white spot in the middle */
1497                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1498                 for (x = 0; x < 128; ++x)
1499                 {
1500                     if(y>62 && y<66 && x>62 && x<66)
1501                         *ptr++ = 0xffffffff;
1502                     else
1503                         *ptr++ = 0xff000000;
1504                 }
1505             }
1506             else
1507             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1508                * (if multiplied with bumpenvmat)
1509               */
1510                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1511                 for (x = 0; x < 128; ++x)
1512                 {
1513                     if(abs(x-64)>abs(y-64))
1514                     {
1515                         if(x < 64)
1516                             *ptr++ = 0xc000;
1517                         else
1518                             *ptr++ = 0x4000;
1519                     }
1520                     else
1521                     {
1522                         if(y < 64)
1523                             *ptr++ = 0x0040;
1524                         else
1525                             *ptr++ = 0x00c0;
1526                     }
1527                 }
1528             }
1529         }
1530         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1531         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1532
1533         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1534         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1535
1536         /* Disable texture filtering */
1537         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1538         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1539         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1540         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1541
1542         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1543         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1544         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1545         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1546     }
1547 }
1548
1549 /* test the behavior of the texbem instruction
1550  * with normal 2D and projective 2D textures
1551  */
1552 static void texbem_test(IDirect3DDevice9 *device)
1553 {
1554     HRESULT hr;
1555     DWORD color;
1556     int i;
1557
1558     static const DWORD pixel_shader_code[] = {
1559         0xffff0101,                         /* ps_1_1*/
1560         0x00000042, 0xb00f0000,             /* tex t0*/
1561         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1562         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1563         0x0000ffff
1564     };
1565     static const DWORD double_texbem_code[] =  {
1566         0xffff0103,                                         /* ps_1_3           */
1567         0x00000042, 0xb00f0000,                             /* tex t0           */
1568         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1569         0x00000042, 0xb00f0002,                             /* tex t2           */
1570         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1571         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1572         0x0000ffff                                          /* end              */
1573     };
1574
1575
1576     static const float quad[][7] = {
1577         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1578         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1579         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1580         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1581     };
1582     static const float quad_proj[][9] = {
1583         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1584         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1585         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1586         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1587     };
1588
1589     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1590         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1591         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1592         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1593         D3DDECL_END()
1594     },{
1595         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1596         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1597         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1598         D3DDECL_END()
1599     } };
1600
1601     /* use asymmetric matrix to test loading */
1602     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1603
1604     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1605     IDirect3DPixelShader9       *pixel_shader       = NULL;
1606     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1607     D3DLOCKED_RECT locked_rect;
1608
1609     generate_bumpmap_textures(device);
1610
1611     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1612     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1613     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1614     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1615     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1616
1617     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1618     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1619
1620     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1621     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1622
1623     for(i=0; i<2; i++)
1624     {
1625         if(i)
1626         {
1627             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1628             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1629         }
1630
1631         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1632         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1633         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1634         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1635
1636         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1637         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1638         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1639         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1640
1641         hr = IDirect3DDevice9_BeginScene(device);
1642         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1643
1644         if(!i)
1645             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1646         else
1647             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1648         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1649
1650         hr = IDirect3DDevice9_EndScene(device);
1651         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1652
1653         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1654         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1655
1656         color = getPixelColor(device, 320-32, 240);
1657         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1658         color = getPixelColor(device, 320+32, 240);
1659         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1660         color = getPixelColor(device, 320, 240-32);
1661         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1662         color = getPixelColor(device, 320, 240+32);
1663         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1664
1665         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1666         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1667         IDirect3DPixelShader9_Release(pixel_shader);
1668
1669         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1670         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1671         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1672     }
1673
1674     /* clean up */
1675     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1676     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1677
1678     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1679     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1680
1681     for(i=0; i<2; i++)
1682     {
1683         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1684         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1685         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1686         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1687         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1688         IDirect3DTexture9_Release(texture);
1689     }
1690
1691     /* Test double texbem */
1692     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1693     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1694     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1695     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1696     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1697     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1698     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1699     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1700
1701     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1702     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1703     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1704     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1705
1706     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1707     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1708
1709     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1710     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1711     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1712     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1713     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1714     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1715
1716     {
1717         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1718 #define tex  0x00ff0000
1719 #define tex1 0x0000ff00
1720 #define origin 0x000000ff
1721         static const DWORD pixel_data[] = {
1722             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1723             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1724             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1725             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1726             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1727             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1728             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1729             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1730         };
1731 #undef tex1
1732 #undef tex2
1733 #undef origin
1734
1735         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1736         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1737         for(i = 0; i < 8; i++) {
1738             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1739         }
1740         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1741         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1742     }
1743
1744     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1745     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1746     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1747     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1748     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1749     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1750     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1751     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1752     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1753     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1754     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1755     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1756
1757     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1758     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1759     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1760     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1761     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1762     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1763
1764     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1765     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1766     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1767     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1768     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1769     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1770
1771     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1772     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1773     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1775     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1776     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1777     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1778     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1779
1780     hr = IDirect3DDevice9_BeginScene(device);
1781     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1782     if(SUCCEEDED(hr)) {
1783         static const float double_quad[] = {
1784             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1785              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1786             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1787              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1788         };
1789
1790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1791         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1792         hr = IDirect3DDevice9_EndScene(device);
1793         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1794     }
1795     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1796     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1797     color = getPixelColor(device, 320, 240);
1798     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1799
1800     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1801     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1802     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1803     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1804     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1805     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1806     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1807     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1808     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1809     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1810
1811     IDirect3DPixelShader9_Release(pixel_shader);
1812     IDirect3DTexture9_Release(texture);
1813     IDirect3DTexture9_Release(texture1);
1814     IDirect3DTexture9_Release(texture2);
1815 }
1816
1817 static void z_range_test(IDirect3DDevice9 *device)
1818 {
1819     const struct vertex quad[] =
1820     {
1821         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1822         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1823         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1824         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1825     };
1826     const struct vertex quad2[] =
1827     {
1828         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1829         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1830         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1831         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1832     };
1833
1834     const struct tvertex quad3[] =
1835     {
1836         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1837         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1838         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1839         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1840     };
1841     const struct tvertex quad4[] =
1842     {
1843         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1844         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1845         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1846         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1847     };
1848     HRESULT hr;
1849     DWORD color;
1850     IDirect3DVertexShader9 *shader;
1851     IDirect3DVertexDeclaration9 *decl;
1852     D3DCAPS9 caps;
1853     const DWORD shader_code[] = {
1854         0xfffe0101,                                     /* vs_1_1           */
1855         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1856         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1857         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1858         0x0000ffff                                      /* end              */
1859     };
1860     static const D3DVERTEXELEMENT9 decl_elements[] = {
1861         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1862         D3DDECL_END()
1863     };
1864     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1865      * then call Present. Then clear the color buffer to make sure it has some defined content
1866      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1867      * by the depth value.
1868      */
1869     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1870     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1871     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1872     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1873
1874     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1875     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1876     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1877     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1878     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1879     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1880     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1881     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1882     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1883     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1884
1885     hr = IDirect3DDevice9_BeginScene(device);
1886     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1887     if(hr == D3D_OK)
1888     {
1889         /* Test the untransformed vertex path */
1890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1891         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1892         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1893         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1895         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1896
1897         /* Test the transformed vertex path */
1898         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1899         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1900
1901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1902         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1903         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1904         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1905         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1906         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1907
1908         hr = IDirect3DDevice9_EndScene(device);
1909         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1910     }
1911
1912     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1913     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1914
1915     /* Do not test the exact corner pixels, but go pretty close to them */
1916
1917     /* Clipped because z > 1.0 */
1918     color = getPixelColor(device, 28, 238);
1919     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1920     color = getPixelColor(device, 28, 241);
1921     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1922
1923     /* Not clipped, > z buffer clear value(0.75) */
1924     color = getPixelColor(device, 31, 238);
1925     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1926     color = getPixelColor(device, 31, 241);
1927     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1928     color = getPixelColor(device, 100, 238);
1929     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1930     color = getPixelColor(device, 100, 241);
1931     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1932
1933     /* Not clipped, < z buffer clear value */
1934     color = getPixelColor(device, 104, 238);
1935     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1936     color = getPixelColor(device, 104, 241);
1937     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1938     color = getPixelColor(device, 318, 238);
1939     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1940     color = getPixelColor(device, 318, 241);
1941     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1942
1943     /* Clipped because z < 0.0 */
1944     color = getPixelColor(device, 321, 238);
1945     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1946     color = getPixelColor(device, 321, 241);
1947     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1948
1949     /* Test the shader path */
1950     IDirect3DDevice9_GetDeviceCaps(device, &caps);
1951     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1952         skip("Vertex shaders not supported\n");
1953         goto out;
1954     }
1955     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1956     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1957     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1958     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1959
1960     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1961
1962     IDirect3DDevice9_SetVertexDeclaration(device, decl);
1963     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1964     IDirect3DDevice9_SetVertexShader(device, shader);
1965     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1966
1967     hr = IDirect3DDevice9_BeginScene(device);
1968     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1969     if(hr == D3D_OK)
1970     {
1971         float colorf[] = {1.0, 0.0, 0.0, 1.0};
1972         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1973         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1974         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1975         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1976         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1977         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1978         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1980         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1981
1982         hr = IDirect3DDevice9_EndScene(device);
1983         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1984     }
1985
1986     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1987     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1988     IDirect3DDevice9_SetVertexShader(device, NULL);
1989     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1990
1991     IDirect3DVertexDeclaration9_Release(decl);
1992     IDirect3DVertexShader9_Release(shader);
1993
1994     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1995     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1996     /* Z < 1.0 */
1997     color = getPixelColor(device, 28, 238);
1998     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1999
2000     /* 1.0 < z < 0.75 */
2001     color = getPixelColor(device, 31, 238);
2002     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2003     color = getPixelColor(device, 100, 238);
2004     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2005
2006     /* 0.75 < z < 0.0 */
2007     color = getPixelColor(device, 104, 238);
2008     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2009     color = getPixelColor(device, 318, 238);
2010     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2011
2012     /* 0.0 < z */
2013     color = getPixelColor(device, 321, 238);
2014     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2015
2016     out:
2017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2018     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2020     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2021     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2022     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2023 }
2024
2025 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2026 {
2027     D3DSURFACE_DESC desc;
2028     D3DLOCKED_RECT l;
2029     HRESULT hr;
2030     unsigned int x, y;
2031     DWORD *mem;
2032
2033     memset(&desc, 0, sizeof(desc));
2034     memset(&l, 0, sizeof(l));
2035     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2036     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2037     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2038     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2039     if(FAILED(hr)) return;
2040
2041     for(y = 0; y < desc.Height; y++)
2042     {
2043         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2044         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2045         {
2046             mem[x] = color;
2047         }
2048     }
2049     hr = IDirect3DSurface9_UnlockRect(surface);
2050     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2051 }
2052
2053 /* This tests a variety of possible StretchRect() situations */
2054 static void stretchrect_test(IDirect3DDevice9 *device)
2055 {
2056     HRESULT hr;
2057     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2058     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2059     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2060     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2061     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2062     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2063     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2064     IDirect3DSurface9 *orig_rt = NULL;
2065     DWORD color;
2066
2067     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2068     ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2069     if(!orig_rt) {
2070         goto out;
2071     }
2072
2073     /* Create our temporary surfaces in system memory */
2074     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2075     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2076     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2077     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2078
2079     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2080     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2081     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2082     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2083     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2084     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2085     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2086
2087     /* Create render target surfaces */
2088     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2089     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2090     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2091     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2092     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2093     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2094
2095     /* Create render target textures */
2096     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2097     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2098     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2099     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2100     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2101     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2102     if (tex_rt32) {
2103         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2104         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2105     }
2106     if (tex_rt64) {
2107         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2108         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2109     }
2110     if (tex_rt_dest64) {
2111         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2112         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2113     }
2114
2115     /* Create regular textures in D3DPOOL_DEFAULT */
2116     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2117     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2118     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2119     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2120     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2121     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2122     if (tex32) {
2123         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2124         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2125     }
2126     if (tex64) {
2127         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2128         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2129     }
2130     if (tex_dest64) {
2131         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2132         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2133     }
2134
2135     /*********************************************************************
2136      * Tests for when the source parameter is an offscreen plain surface *
2137      *********************************************************************/
2138
2139     /* Fill the offscreen 64x64 surface with green */
2140     if (surf_offscreen64)
2141         fill_surface(surf_offscreen64, 0xff00ff00);
2142
2143     /* offscreenplain ==> offscreenplain, same size */
2144     if(surf_offscreen64 && surf_offscreen_dest64) {
2145         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2146         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2147
2148         if (hr == D3D_OK) {
2149             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2150             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2151         }
2152     }
2153
2154     /* offscreenplain ==> rendertarget texture, same size */
2155     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2156         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2157         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2158
2159         /* We can't lock rendertarget textures, so copy to our temp surface first */
2160         if (hr == D3D_OK) {
2161             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2162             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2163         }
2164
2165         if (hr == D3D_OK) {
2166             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2167             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2168         }
2169     }
2170
2171     /* offscreenplain ==> rendertarget surface, same size */
2172     if(surf_offscreen64 && surf_rt_dest64) {
2173         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2174         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2175
2176         if (hr == D3D_OK) {
2177             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2178             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2179         }
2180     }
2181
2182     /* offscreenplain ==> texture, same size (should fail) */
2183     if(surf_offscreen64 && surf_tex_dest64) {
2184         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2185         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2186     }
2187
2188     /* Fill the smaller offscreen surface with red */
2189     fill_surface(surf_offscreen32, 0xffff0000);
2190
2191     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2192     if(surf_offscreen32 && surf_offscreen64) {
2193         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2194         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2195     }
2196
2197     /* offscreenplain ==> rendertarget texture, scaling */
2198     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2199         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2200         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2201
2202         /* We can't lock rendertarget textures, so copy to our temp surface first */
2203         if (hr == D3D_OK) {
2204             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2205             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2206         }
2207
2208         if (hr == D3D_OK) {
2209             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2210             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2211         }
2212     }
2213
2214     /* offscreenplain ==> rendertarget surface, scaling */
2215     if(surf_offscreen32 && surf_rt_dest64) {
2216         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2217         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2218
2219         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2220         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2221     }
2222
2223     /* offscreenplain ==> texture, scaling (should fail) */
2224     if(surf_offscreen32 && surf_tex_dest64) {
2225         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2226         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2227     }
2228
2229     /************************************************************
2230      * Tests for when the source parameter is a regular texture *
2231      ************************************************************/
2232
2233     /* Fill the surface of the regular texture with blue */
2234     if (surf_tex64 && surf_temp64) {
2235         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2236         fill_surface(surf_temp64, 0xff0000ff);
2237         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2238         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2239     }
2240
2241     /* texture ==> offscreenplain, same size */
2242     if(surf_tex64 && surf_offscreen64) {
2243         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2244         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2245     }
2246
2247     /* texture ==> rendertarget texture, same size */
2248     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2249         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2250         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2251
2252         /* We can't lock rendertarget textures, so copy to our temp surface first */
2253         if (hr == D3D_OK) {
2254             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2255             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2256         }
2257
2258         if (hr == D3D_OK) {
2259             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2260             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2261         }
2262     }
2263
2264     /* texture ==> rendertarget surface, same size */
2265     if(surf_tex64 && surf_rt_dest64) {
2266         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2267         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2268
2269         if (hr == D3D_OK) {
2270             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2271             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2272         }
2273     }
2274
2275     /* texture ==> texture, same size (should fail) */
2276     if(surf_tex64 && surf_tex_dest64) {
2277         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2278         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2279     }
2280
2281     /* Fill the surface of the smaller regular texture with red */
2282     if (surf_tex32 && surf_temp32) {
2283         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2284         fill_surface(surf_temp32, 0xffff0000);
2285         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2286         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2287     }
2288
2289     /* texture ==> offscreenplain, scaling (should fail) */
2290     if(surf_tex32 && surf_offscreen64) {
2291         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2292         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2293     }
2294
2295     /* texture ==> rendertarget texture, scaling */
2296     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2297         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2298         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2299
2300         /* We can't lock rendertarget textures, so copy to our temp surface first */
2301         if (hr == D3D_OK) {
2302             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2303             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2304         }
2305
2306         if (hr == D3D_OK) {
2307             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2308             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2309         }
2310     }
2311
2312     /* texture ==> rendertarget surface, scaling */
2313     if(surf_tex32 && surf_rt_dest64) {
2314         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2315         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2316
2317         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2318         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2319     }
2320
2321     /* texture ==> texture, scaling (should fail) */
2322     if(surf_tex32 && surf_tex_dest64) {
2323         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2324         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2325     }
2326
2327     /*****************************************************************
2328      * Tests for when the source parameter is a rendertarget texture *
2329      *****************************************************************/
2330
2331     /* Fill the surface of the rendertarget texture with white */
2332     if (surf_tex_rt64 && surf_temp64) {
2333         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2334         fill_surface(surf_temp64, 0xffffffff);
2335         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2336         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2337     }
2338
2339     /* rendertarget texture ==> offscreenplain, same size */
2340     if(surf_tex_rt64 && surf_offscreen64) {
2341         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2342         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2343     }
2344
2345     /* rendertarget texture ==> rendertarget texture, same size */
2346     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2347         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2348         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2349
2350         /* We can't lock rendertarget textures, so copy to our temp surface first */
2351         if (hr == D3D_OK) {
2352             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2353             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2354         }
2355
2356         if (hr == D3D_OK) {
2357             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2358             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2359         }
2360     }
2361
2362     /* rendertarget texture ==> rendertarget surface, same size */
2363     if(surf_tex_rt64 && surf_rt_dest64) {
2364         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2365         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2366
2367         if (hr == D3D_OK) {
2368             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2369             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2370         }
2371     }
2372
2373     /* rendertarget texture ==> texture, same size (should fail) */
2374     if(surf_tex_rt64 && surf_tex_dest64) {
2375         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2376         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2377     }
2378
2379     /* Fill the surface of the smaller rendertarget texture with red */
2380     if (surf_tex_rt32 && surf_temp32) {
2381         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2382         fill_surface(surf_temp32, 0xffff0000);
2383         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2384         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2385     }
2386
2387     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2388     if(surf_tex_rt32 && surf_offscreen64) {
2389         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2390         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2391     }
2392
2393     /* rendertarget texture ==> rendertarget texture, scaling */
2394     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2395         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2396         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2397
2398         /* We can't lock rendertarget textures, so copy to our temp surface first */
2399         if (hr == D3D_OK) {
2400             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2401             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2402         }
2403
2404         if (hr == D3D_OK) {
2405             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2406             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2407         }
2408     }
2409
2410     /* rendertarget texture ==> rendertarget surface, scaling */
2411     if(surf_tex_rt32 && surf_rt_dest64) {
2412         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2413         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2414
2415         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2416         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2417     }
2418
2419     /* rendertarget texture ==> texture, scaling (should fail) */
2420     if(surf_tex_rt32 && surf_tex_dest64) {
2421         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2422         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2423     }
2424
2425     /*****************************************************************
2426      * Tests for when the source parameter is a rendertarget surface *
2427      *****************************************************************/
2428
2429     /* Fill the surface of the rendertarget surface with black */
2430     if (surf_rt64)
2431         fill_surface(surf_rt64, 0xff000000);
2432
2433     /* rendertarget texture ==> offscreenplain, same size */
2434     if(surf_rt64 && surf_offscreen64) {
2435         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2436         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2437     }
2438
2439     /* rendertarget surface ==> rendertarget texture, same size */
2440     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2441         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2442         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2443
2444         /* We can't lock rendertarget textures, so copy to our temp surface first */
2445         if (hr == D3D_OK) {
2446             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2447             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2448         }
2449
2450         if (hr == D3D_OK) {
2451             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2452             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2453         }
2454     }
2455
2456     /* rendertarget surface ==> rendertarget surface, same size */
2457     if(surf_rt64 && surf_rt_dest64) {
2458         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2459         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2460
2461         if (hr == D3D_OK) {
2462             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2463             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2464         }
2465     }
2466
2467     /* rendertarget surface ==> texture, same size (should fail) */
2468     if(surf_rt64 && surf_tex_dest64) {
2469         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2470         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2471     }
2472
2473     /* Fill the surface of the smaller rendertarget texture with red */
2474     if (surf_rt32)
2475         fill_surface(surf_rt32, 0xffff0000);
2476
2477     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2478     if(surf_rt32 && surf_offscreen64) {
2479         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2481     }
2482
2483     /* rendertarget surface ==> rendertarget texture, scaling */
2484     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2486         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2487
2488         /* We can't lock rendertarget textures, so copy to our temp surface first */
2489         if (hr == D3D_OK) {
2490             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2491             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2492         }
2493
2494         if (hr == D3D_OK) {
2495             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2496             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2497         }
2498     }
2499
2500     /* rendertarget surface ==> rendertarget surface, scaling */
2501     if(surf_rt32 && surf_rt_dest64) {
2502         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2503         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2504
2505         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2506         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2507     }
2508
2509     /* rendertarget surface ==> texture, scaling (should fail) */
2510     if(surf_rt32 && surf_tex_dest64) {
2511         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2512         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2513     }
2514
2515     /* TODO: Test when source and destination RECT parameters are given... */
2516     /* TODO: Test format conversions */
2517
2518
2519 out:
2520     /* Clean up */
2521     if (surf_rt32)
2522         IDirect3DSurface9_Release(surf_rt32);
2523     if (surf_rt64)
2524         IDirect3DSurface9_Release(surf_rt64);
2525     if (surf_rt_dest64)
2526         IDirect3DSurface9_Release(surf_rt_dest64);
2527     if (surf_temp32)
2528         IDirect3DSurface9_Release(surf_temp32);
2529     if (surf_temp64)
2530         IDirect3DSurface9_Release(surf_temp64);
2531     if (surf_offscreen32)
2532         IDirect3DSurface9_Release(surf_offscreen32);
2533     if (surf_offscreen64)
2534         IDirect3DSurface9_Release(surf_offscreen64);
2535     if (surf_offscreen_dest64)
2536         IDirect3DSurface9_Release(surf_offscreen_dest64);
2537
2538     if (tex_rt32) {
2539         if (surf_tex_rt32)
2540             IDirect3DSurface9_Release(surf_tex_rt32);
2541         IDirect3DTexture9_Release(tex_rt32);
2542     }
2543     if (tex_rt64) {
2544         if (surf_tex_rt64)
2545             IDirect3DSurface9_Release(surf_tex_rt64);
2546         IDirect3DTexture9_Release(tex_rt64);
2547     }
2548     if (tex_rt_dest64) {
2549         if (surf_tex_rt_dest64)
2550             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2551         IDirect3DTexture9_Release(tex_rt_dest64);
2552     }
2553     if (tex32) {
2554         if (surf_tex32)
2555             IDirect3DSurface9_Release(surf_tex32);
2556         IDirect3DTexture9_Release(tex32);
2557     }
2558     if (tex64) {
2559         if (surf_tex64)
2560             IDirect3DSurface9_Release(surf_tex64);
2561         IDirect3DTexture9_Release(tex64);
2562     }
2563     if (tex_dest64) {
2564         if (surf_tex_dest64)
2565             IDirect3DSurface9_Release(surf_tex_dest64);
2566         IDirect3DTexture9_Release(tex_dest64);
2567     }
2568
2569     if (orig_rt) {
2570         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2571         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2572         IDirect3DSurface9_Release(orig_rt);
2573     }
2574 }
2575
2576 static void maxmip_test(IDirect3DDevice9 *device)
2577 {
2578     IDirect3DTexture9 *texture = NULL;
2579     IDirect3DSurface9 *surface = NULL;
2580     HRESULT hr;
2581     DWORD color;
2582     const float quads[] = {
2583         -1.0,   -1.0,   0.0,    0.0,    0.0,
2584         -1.0,    0.0,   0.0,    0.0,    1.0,
2585          0.0,   -1.0,   0.0,    1.0,    0.0,
2586          0.0,    0.0,   0.0,    1.0,    1.0,
2587
2588          0.0,   -1.0,   0.0,    0.0,    0.0,
2589          0.0,    0.0,   0.0,    0.0,    1.0,
2590          1.0,   -1.0,   0.0,    1.0,    0.0,
2591          1.0,    0.0,   0.0,    1.0,    1.0,
2592
2593          0.0,    0.0,   0.0,    0.0,    0.0,
2594          0.0,    1.0,   0.0,    0.0,    1.0,
2595          1.0,    0.0,   0.0,    1.0,    0.0,
2596          1.0,    1.0,   0.0,    1.0,    1.0,
2597
2598         -1.0,    0.0,   0.0,    0.0,    0.0,
2599         -1.0,    1.0,   0.0,    0.0,    1.0,
2600          0.0,    0.0,   0.0,    1.0,    0.0,
2601          0.0,    1.0,   0.0,    1.0,    1.0,
2602     };
2603
2604     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2605     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2606
2607     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2608                                         &texture, NULL);
2609     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2610     if(!texture)
2611     {
2612         skip("Failed to create test texture\n");
2613         return;
2614     }
2615
2616     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2617     fill_surface(surface, 0xffff0000);
2618     IDirect3DSurface9_Release(surface);
2619     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2620     fill_surface(surface, 0xff00ff00);
2621     IDirect3DSurface9_Release(surface);
2622     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2623     fill_surface(surface, 0xff0000ff);
2624     IDirect3DSurface9_Release(surface);
2625
2626     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2627     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2628     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2629     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2630
2631     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2632     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2633
2634     hr = IDirect3DDevice9_BeginScene(device);
2635     if(SUCCEEDED(hr))
2636     {
2637         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2638         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2639         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2640         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2641
2642         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2643         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2644         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2645         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2646
2647         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2648         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2649         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2650         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2651
2652         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2653         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2654         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2655         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2656         hr = IDirect3DDevice9_EndScene(device);
2657     }
2658
2659     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2660     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2661     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2662     color = getPixelColor(device, 160, 360);
2663     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2664     color = getPixelColor(device, 160, 120);
2665     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2666     color = getPixelColor(device, 480, 120);
2667     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2668     color = getPixelColor(device, 480, 360);
2669     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2670
2671     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2672     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2673
2674     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2675     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2676
2677     hr = IDirect3DDevice9_BeginScene(device);
2678     if(SUCCEEDED(hr))
2679     {
2680         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2681         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2682         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2683         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2684
2685         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2686         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2687         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2688         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2689
2690         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2691         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2693         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2694
2695         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2696         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2697         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2698         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2699         hr = IDirect3DDevice9_EndScene(device);
2700     }
2701
2702     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2703     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2704     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2705     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2706
2707     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2708     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2709     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2710      * samples from the highest level in the texture(level 2)
2711      */
2712     color = getPixelColor(device, 160, 360);
2713     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2714     color = getPixelColor(device, 160, 120);
2715     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2716     color = getPixelColor(device, 480, 120);
2717     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2718     color = getPixelColor(device, 480, 360);
2719     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2720
2721     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2722     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2723     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2724     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2725     IDirect3DTexture9_Release(texture);
2726 }
2727
2728 static void release_buffer_test(IDirect3DDevice9 *device)
2729 {
2730     IDirect3DVertexBuffer9 *vb = NULL;
2731     IDirect3DIndexBuffer9 *ib = NULL;
2732     HRESULT hr;
2733     BYTE *data;
2734     long ref;
2735
2736     static const struct vertex quad[] = {
2737         {-1.0,      -1.0,       0.1,        0xffff0000},
2738         {-1.0,       1.0,       0.1,        0xffff0000},
2739         { 1.0,       1.0,       0.1,        0xffff0000},
2740
2741         {-1.0,      -1.0,       0.1,        0xff00ff00},
2742         {-1.0,       1.0,       0.1,        0xff00ff00},
2743         { 1.0,       1.0,       0.1,        0xff00ff00}
2744     };
2745     short indices[] = {3, 4, 5};
2746
2747     /* Index and vertex buffers should always be creatable */
2748     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2749                                               D3DPOOL_MANAGED, &vb, NULL);
2750     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2751     if(!vb) {
2752         skip("Failed to create a vertex buffer\n");
2753         return;
2754     }
2755     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2756     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2757     if(!ib) {
2758         skip("Failed to create an index buffer\n");
2759         return;
2760     }
2761
2762     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2763     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2764     memcpy(data, quad, sizeof(quad));
2765     hr = IDirect3DVertexBuffer9_Unlock(vb);
2766     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2767
2768     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2769     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2770     memcpy(data, indices, sizeof(indices));
2771     hr = IDirect3DIndexBuffer9_Unlock(ib);
2772     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2773
2774     hr = IDirect3DDevice9_SetIndices(device, ib);
2775     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %s\n", DXGetErrorString9(hr));
2776     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2777     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
2778     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2779     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2780
2781     /* Now destroy the bound index buffer and draw again */
2782     ref = IDirect3DIndexBuffer9_Release(ib);
2783     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2784
2785     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2786     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2787
2788     hr = IDirect3DDevice9_BeginScene(device);
2789     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2790     if(SUCCEEDED(hr))
2791     {
2792         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2793          * making assumptions about the indices or vertices
2794          */
2795         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2796         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2797         hr = IDirect3DDevice9_EndScene(device);
2798         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2799     }
2800
2801     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2802     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2803
2804     hr = IDirect3DDevice9_SetIndices(device, NULL);
2805     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2806     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2807     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2808
2809     /* Index buffer was already destroyed as part of the test */
2810     IDirect3DVertexBuffer9_Release(vb);
2811 }
2812
2813 static void float_texture_test(IDirect3DDevice9 *device)
2814 {
2815     IDirect3D9 *d3d = NULL;
2816     HRESULT hr;
2817     IDirect3DTexture9 *texture = NULL;
2818     D3DLOCKED_RECT lr;
2819     float *data;
2820     DWORD color;
2821     float quad[] = {
2822         -1.0,      -1.0,       0.1,     0.0,    0.0,
2823         -1.0,       1.0,       0.1,     0.0,    1.0,
2824          1.0,      -1.0,       0.1,     1.0,    0.0,
2825          1.0,       1.0,       0.1,     1.0,    1.0,
2826     };
2827
2828     memset(&lr, 0, sizeof(lr));
2829     IDirect3DDevice9_GetDirect3D(device, &d3d);
2830     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2831                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2832         skip("D3DFMT_R32F textures not supported\n");
2833         goto out;
2834     }
2835
2836     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2837                                         D3DPOOL_MANAGED, &texture, NULL);
2838     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2839     if(!texture) {
2840         skip("Failed to create R32F texture\n");
2841         goto out;
2842     }
2843
2844     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2845     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2846     data = lr.pBits;
2847     *data = 0.0;
2848     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2849     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2850
2851     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2852     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2853
2854     hr = IDirect3DDevice9_BeginScene(device);
2855     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2856     if(SUCCEEDED(hr))
2857     {
2858         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2859         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2860
2861         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2862         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2863
2864         hr = IDirect3DDevice9_EndScene(device);
2865         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2866     }
2867     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2868     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2869
2870     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2871     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2872
2873     color = getPixelColor(device, 240, 320);
2874     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2875
2876 out:
2877     if(texture) IDirect3DTexture9_Release(texture);
2878     IDirect3D9_Release(d3d);
2879 }
2880
2881 static void g16r16_texture_test(IDirect3DDevice9 *device)
2882 {
2883     IDirect3D9 *d3d = NULL;
2884     HRESULT hr;
2885     IDirect3DTexture9 *texture = NULL;
2886     D3DLOCKED_RECT lr;
2887     DWORD *data;
2888     DWORD color, red, green, blue;
2889     float quad[] = {
2890        -1.0,      -1.0,       0.1,     0.0,    0.0,
2891        -1.0,       1.0,       0.1,     0.0,    1.0,
2892         1.0,      -1.0,       0.1,     1.0,    0.0,
2893         1.0,       1.0,       0.1,     1.0,    1.0,
2894     };
2895
2896     memset(&lr, 0, sizeof(lr));
2897     IDirect3DDevice9_GetDirect3D(device, &d3d);
2898     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2899        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2900            skip("D3DFMT_G16R16 textures not supported\n");
2901            goto out;
2902     }
2903
2904     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2905                                         D3DPOOL_MANAGED, &texture, NULL);
2906     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2907     if(!texture) {
2908         skip("Failed to create D3DFMT_G16R16 texture\n");
2909         goto out;
2910     }
2911
2912     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2913     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2914     data = lr.pBits;
2915     *data = 0x0f00f000;
2916     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2917     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2918
2919     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2920     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2921
2922     hr = IDirect3DDevice9_BeginScene(device);
2923     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2924     if(SUCCEEDED(hr))
2925     {
2926         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2927         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2928
2929         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2930         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2931
2932         hr = IDirect3DDevice9_EndScene(device);
2933         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2934     }
2935     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2936     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2937
2938     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2939     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2940
2941     color = getPixelColor(device, 240, 320);
2942     red   = (color & 0x00ff0000) >> 16;
2943     green = (color & 0x0000ff00) >>  8;
2944     blue  = (color & 0x000000ff) >>  0;
2945     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2946        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2947
2948 out:
2949     if(texture) IDirect3DTexture9_Release(texture);
2950     IDirect3D9_Release(d3d);
2951 }
2952
2953 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2954 {
2955     HRESULT hr;
2956     IDirect3D9 *d3d;
2957     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2958     D3DCAPS9 caps;
2959     IDirect3DTexture9 *texture = NULL;
2960     IDirect3DVolumeTexture9 *volume = NULL;
2961     unsigned int x, y, z;
2962     D3DLOCKED_RECT lr;
2963     D3DLOCKED_BOX lb;
2964     DWORD color;
2965     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2966     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2967                            0.0, 1.0, 0.0, 0.0,
2968                            0.0, 0.0, 1.0, 0.0,
2969                            0.0, 0.0, 0.0, 1.0};
2970     static const D3DVERTEXELEMENT9 decl_elements[] = {
2971         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2972         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2973         D3DDECL_END()
2974     };
2975     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2976         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2977         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2978         D3DDECL_END()
2979     };
2980     static const D3DVERTEXELEMENT9 decl_elements3[] = {
2981         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2982         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2983         D3DDECL_END()
2984     };
2985     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2986                                                  0x00, 0xff, 0x00, 0x00,
2987                                                  0x00, 0x00, 0x00, 0x00,
2988                                                  0x00, 0x00, 0x00, 0x00};
2989
2990     memset(&lr, 0, sizeof(lr));
2991     memset(&lb, 0, sizeof(lb));
2992     IDirect3DDevice9_GetDirect3D(device, &d3d);
2993     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2994                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2995         fmt = D3DFMT_A16B16G16R16;
2996     }
2997     IDirect3D9_Release(d3d);
2998
2999     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3000     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3001     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3002     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3003     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3004     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3005     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3006     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
3007     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3008     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
3009     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3010     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
3011     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3012     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
3013     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3014     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3015     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3016     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3017     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3018     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3020     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3021     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3022     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3023
3024     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3025     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3026     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3027                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3028     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3029     if(!texture) {
3030         skip("Failed to create the test texture\n");
3031         return;
3032     }
3033
3034     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3035      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3036      * 1.0 in red and green for the x and y coords
3037      */
3038     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3039     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3040     for(y = 0; y < caps.MaxTextureHeight; y++) {
3041         for(x = 0; x < caps.MaxTextureWidth; x++) {
3042             double r_f = (double) y / (double) caps.MaxTextureHeight;
3043             double g_f = (double) x / (double) caps.MaxTextureWidth;
3044             if(fmt == D3DFMT_A16B16G16R16) {
3045                 unsigned short r, g;
3046                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3047                 r = (unsigned short) (r_f * 65536.0);
3048                 g = (unsigned short) (g_f * 65536.0);
3049                 dst[0] = r;
3050                 dst[1] = g;
3051                 dst[2] = 0;
3052                 dst[3] = 65535;
3053             } else {
3054                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3055                 unsigned char r = (unsigned char) (r_f * 255.0);
3056                 unsigned char g = (unsigned char) (g_f * 255.0);
3057                 dst[0] = 0;
3058                 dst[1] = g;
3059                 dst[2] = r;
3060                 dst[3] = 255;
3061             }
3062         }
3063     }
3064     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3065     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3066     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3067     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3068
3069     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3070     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3071     hr = IDirect3DDevice9_BeginScene(device);
3072     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3073     if(SUCCEEDED(hr))
3074     {
3075         float quad1[] = {
3076             -1.0,      -1.0,       0.1,     1.0,    1.0,
3077             -1.0,       0.0,       0.1,     1.0,    1.0,
3078              0.0,      -1.0,       0.1,     1.0,    1.0,
3079              0.0,       0.0,       0.1,     1.0,    1.0,
3080         };
3081         float quad2[] = {
3082             -1.0,       0.0,       0.1,     1.0,    1.0,
3083             -1.0,       1.0,       0.1,     1.0,    1.0,
3084              0.0,       0.0,       0.1,     1.0,    1.0,
3085              0.0,       1.0,       0.1,     1.0,    1.0,
3086         };
3087         float quad3[] = {
3088              0.0,       0.0,       0.1,     0.5,    0.5,
3089              0.0,       1.0,       0.1,     0.5,    0.5,
3090              1.0,       0.0,       0.1,     0.5,    0.5,
3091              1.0,       1.0,       0.1,     0.5,    0.5,
3092         };
3093         float quad4[] = {
3094              320,       480,       0.1,     1.0,    0.0,    1.0,
3095              320,       240,       0.1,     1.0,    0.0,    1.0,
3096              640,       480,       0.1,     1.0,    0.0,    1.0,
3097              640,       240,       0.1,     1.0,    0.0,    1.0,
3098         };
3099         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3100                           0.0, 0.0, 0.0, 0.0,
3101                           0.0, 0.0, 0.0, 0.0,
3102                           0.0, 0.0, 0.0, 0.0};
3103
3104         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3105         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3106         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3107         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3108         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3109
3110         /* What happens with transforms enabled? */
3111         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3112         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3113         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3114         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3115
3116         /* What happens if 4 coords are used, but only 2 given ?*/
3117         mat[8] = 1.0;
3118         mat[13] = 1.0;
3119         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3120         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3121         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3122         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3124         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3125
3126         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3127          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3128          * due to the coords in the vertices. (turns out red, indeed)
3129          */
3130         memset(mat, 0, sizeof(mat));
3131         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3133         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3134         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3135         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3136         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139
3140         hr = IDirect3DDevice9_EndScene(device);
3141         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3142     }
3143     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3144     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3145     color = getPixelColor(device, 160, 360);
3146     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3147     color = getPixelColor(device, 160, 120);
3148     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3149     color = getPixelColor(device, 480, 120);
3150     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3151     color = getPixelColor(device, 480, 360);
3152     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3153
3154     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3155     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3156
3157     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3158     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3159     hr = IDirect3DDevice9_BeginScene(device);
3160     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3161     if(SUCCEEDED(hr))
3162     {
3163         float quad1[] = {
3164             -1.0,      -1.0,       0.1,     0.8,    0.2,
3165             -1.0,       0.0,       0.1,     0.8,    0.2,
3166              0.0,      -1.0,       0.1,     0.8,    0.2,
3167              0.0,       0.0,       0.1,     0.8,    0.2,
3168         };
3169         float quad2[] = {
3170             -1.0,       0.0,       0.1,     0.5,    1.0,
3171             -1.0,       1.0,       0.1,     0.5,    1.0,
3172              0.0,       0.0,       0.1,     0.5,    1.0,
3173              0.0,       1.0,       0.1,     0.5,    1.0,
3174         };
3175         float quad3[] = {
3176              0.0,       0.0,       0.1,     0.5,    1.0,
3177              0.0,       1.0,       0.1,     0.5,    1.0,
3178              1.0,       0.0,       0.1,     0.5,    1.0,
3179              1.0,       1.0,       0.1,     0.5,    1.0,
3180         };
3181         float quad4[] = {
3182              0.0,      -1.0,       0.1,     0.8,    0.2,
3183              0.0,       0.0,       0.1,     0.8,    0.2,
3184              1.0,      -1.0,       0.1,     0.8,    0.2,
3185              1.0,       0.0,       0.1,     0.8,    0.2,
3186         };
3187         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3188                           0.0, 0.0, 0.0, 0.0,
3189                           0.0, 1.0, 0.0, 0.0,
3190                           0.0, 0.0, 0.0, 0.0};
3191
3192         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3193          */
3194         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3195         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3196         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3197         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3198
3199         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3200         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3201
3202         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3203          * it behaves like COUNT2 because normal textures require 2 coords
3204          */
3205         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3206         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3207         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3208         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3209
3210         /* Just to be sure, the same as quad2 above */
3211         memset(mat, 0, sizeof(mat));
3212         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3213         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3214         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3215         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3216         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3217         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3218
3219         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3220          * used? And what happens to the first?
3221          */
3222         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3223         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3225         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3226
3227         hr = IDirect3DDevice9_EndScene(device);
3228         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3229     }
3230     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3231     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3232     color = getPixelColor(device, 160, 360);
3233     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3234     color = getPixelColor(device, 160, 120);
3235     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3236     color = getPixelColor(device, 480, 120);
3237     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3238        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3239     color = getPixelColor(device, 480, 360);
3240     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3241        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3242
3243     IDirect3DTexture9_Release(texture);
3244
3245     /* Test projected textures, without any fancy matrices */
3246     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3247     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3248     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3249     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3250     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3251     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3252     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3253     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3254
3255     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3256     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3257     for(x = 0; x < 4; x++) {
3258         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3259     }
3260     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3261     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3262     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3263     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3264
3265     hr = IDirect3DDevice9_BeginScene(device);
3266     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3267     if(SUCCEEDED(hr))
3268     {
3269         const float proj_quads[] = {
3270            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3271             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3272            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3273             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3274            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3275             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3276            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3277             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3278         };
3279
3280         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3281         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3283         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3284
3285         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3286         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3287         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3288         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3289
3290         hr = IDirect3DDevice9_EndScene(device);
3291         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3292     }
3293
3294     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3295     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3296     IDirect3DTexture9_Release(texture);
3297
3298     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3299     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3300     color = getPixelColor(device, 158, 118);
3301     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3302     color = getPixelColor(device, 162, 118);
3303     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3304     color = getPixelColor(device, 158, 122);
3305     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3306     color = getPixelColor(device, 162, 122);
3307     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3308
3309     color = getPixelColor(device, 158, 178);
3310     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3311     color = getPixelColor(device, 162, 178);
3312     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3313     color = getPixelColor(device, 158, 182);
3314     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3315     color = getPixelColor(device, 162, 182);
3316     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3317
3318     color = getPixelColor(device, 318, 118);
3319     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3320     color = getPixelColor(device, 322, 118);
3321     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3322     color = getPixelColor(device, 318, 122);
3323     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3324     color = getPixelColor(device, 322, 122);
3325     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3326
3327     color = getPixelColor(device, 318, 178);
3328     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3329     color = getPixelColor(device, 322, 178);
3330     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3331     color = getPixelColor(device, 318, 182);
3332     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3333     color = getPixelColor(device, 322, 182);
3334     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3335
3336     color = getPixelColor(device, 238, 298);
3337     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3338     color = getPixelColor(device, 242, 298);
3339     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3340     color = getPixelColor(device, 238, 302);
3341     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3342     color = getPixelColor(device, 242, 302);
3343     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3344
3345     color = getPixelColor(device, 238, 388);
3346     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3347     color = getPixelColor(device, 242, 388);
3348     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3349     color = getPixelColor(device, 238, 392);
3350     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3351     color = getPixelColor(device, 242, 392);
3352     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3353
3354     color = getPixelColor(device, 478, 298);
3355     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3356     color = getPixelColor(device, 482, 298);
3357     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3358     color = getPixelColor(device, 478, 302);
3359     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3360     color = getPixelColor(device, 482, 302);
3361     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3362
3363     color = getPixelColor(device, 478, 388);
3364     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3365     color = getPixelColor(device, 482, 388);
3366     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3367     color = getPixelColor(device, 478, 392);
3368     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3369     color = getPixelColor(device, 482, 392);
3370     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3371
3372     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3373     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3374     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3375      * Thus watch out if sampling from texels between 0 and 1.
3376      */
3377     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3378     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3379        "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3380     if(!volume) {
3381         skip("Failed to create a volume texture\n");
3382         goto out;
3383     }
3384
3385     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3386     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3387     for(z = 0; z < 32; z++) {
3388         for(y = 0; y < 32; y++) {
3389             for(x = 0; x < 32; x++) {
3390                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3391                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3392                 float r_f = (float) x / 31.0;
3393                 float g_f = (float) y / 31.0;
3394                 float b_f = (float) z / 31.0;
3395
3396                 if(fmt == D3DFMT_A16B16G16R16) {
3397                     unsigned short *mem_s = mem;
3398                     mem_s[0]  = r_f * 65535.0;
3399                     mem_s[1]  = g_f * 65535.0;
3400                     mem_s[2]  = b_f * 65535.0;
3401                     mem_s[3]  = 65535;
3402                 } else {
3403                     unsigned char *mem_c = mem;
3404                     mem_c[0]  = b_f * 255.0;
3405                     mem_c[1]  = g_f * 255.0;
3406                     mem_c[2]  = r_f * 255.0;
3407                     mem_c[3]  = 255;
3408                 }
3409             }
3410         }
3411     }
3412     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3413     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3414
3415     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3416     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3417
3418     hr = IDirect3DDevice9_BeginScene(device);
3419     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3420     if(SUCCEEDED(hr))
3421     {
3422         float quad1[] = {
3423             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3424             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3425              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3426              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3427         };
3428         float quad2[] = {
3429             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3430             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3431              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3432              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3433         };
3434         float quad3[] = {
3435              0.0,       0.0,       0.1,     0.0,    0.0,
3436              0.0,       1.0,       0.1,     0.0,    0.0,
3437              1.0,       0.0,       0.1,     0.0,    0.0,
3438              1.0,       1.0,       0.1,     0.0,    0.0
3439         };
3440         float quad4[] = {
3441              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3442              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3443              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3444              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3445         };
3446         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3447                          0.0, 0.0, 1.0, 0.0,
3448                          0.0, 1.0, 0.0, 0.0,
3449                          0.0, 0.0, 0.0, 1.0};
3450         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3451         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3452
3453         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3454          * values
3455          */
3456         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3457         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3458         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3459         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3460         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3461         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3462
3463         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3464          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3465          * otherwise the w will be missing(blue).
3466          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3467          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3468          */
3469         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3470         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3471         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3472         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3473
3474         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3475         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3476         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3477         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3478         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3479         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3480         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3481         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3482         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3483
3484         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3485          * disable. ATI extends it up to the amount of values needed for the volume texture
3486          */
3487         memset(mat, 0, sizeof(mat));
3488         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3489         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3490         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3491         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3492         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3493         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3495         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3496
3497         hr = IDirect3DDevice9_EndScene(device);
3498         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3499     }
3500     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3501     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3502
3503     color = getPixelColor(device, 160, 360);
3504     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3505     color = getPixelColor(device, 160, 120);
3506     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3507        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3508     color = getPixelColor(device, 480, 120);
3509     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3510     color = getPixelColor(device, 480, 360);
3511     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3512
3513     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3514     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3515     hr = IDirect3DDevice9_BeginScene(device);
3516     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3517     if(SUCCEEDED(hr))
3518     {
3519         float quad1[] = {
3520             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3521             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3522              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3523              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3524         };
3525         float quad2[] = {
3526             -1.0,       0.0,       0.1,
3527             -1.0,       1.0,       0.1,
3528              0.0,       0.0,       0.1,
3529              0.0,       1.0,       0.1,
3530         };
3531         float quad3[] = {
3532              0.0,       0.0,       0.1,     1.0,
3533              0.0,       1.0,       0.1,     1.0,
3534              1.0,       0.0,       0.1,     1.0,
3535              1.0,       1.0,       0.1,     1.0
3536         };
3537         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3538                            0.0, 0.0, 0.0, 0.0,
3539                            0.0, 0.0, 0.0, 0.0,
3540                            0.0, 1.0, 0.0, 0.0};
3541         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3542                            1.0, 0.0, 0.0, 0.0,
3543                            0.0, 1.0, 0.0, 0.0,
3544                            0.0, 0.0, 1.0, 0.0};
3545         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3546         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3547
3548         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3549          */
3550         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3551         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3552         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3553         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3554         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3555         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3556
3557         /* None passed */
3558         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3559         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3560         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3561         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3563         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3564
3565         /* 4 used, 1 passed */
3566         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3567         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3568         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3569         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3570         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3571         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3572
3573         hr = IDirect3DDevice9_EndScene(device);
3574         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3575     }
3576     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3577     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3578     color = getPixelColor(device, 160, 360);
3579     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3580     color = getPixelColor(device, 160, 120);
3581     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3582     color = getPixelColor(device, 480, 120);
3583     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3584     /* Quad4: unused */
3585
3586     IDirect3DVolumeTexture9_Release(volume);
3587
3588     out:
3589     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3590     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3591     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3592     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3593     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3594     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3595     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3596     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3597     IDirect3DVertexDeclaration9_Release(decl);
3598     IDirect3DVertexDeclaration9_Release(decl2);
3599     IDirect3DVertexDeclaration9_Release(decl3);
3600 }
3601
3602 static void texdepth_test(IDirect3DDevice9 *device)
3603 {
3604     IDirect3DPixelShader9 *shader;
3605     HRESULT hr;
3606     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3607     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3608     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3609     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3610     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3611     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3612     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3613     DWORD shader_code[] = {
3614         0xffff0104,                                                                 /* ps_1_4               */
3615         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3616         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3617         0x0000fffd,                                                                 /* phase                */
3618         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3619         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3620         0x0000ffff                                                                  /* end                  */
3621     };
3622     DWORD color;
3623     float vertex[] = {
3624        -1.0,   -1.0,    0.0,
3625         1.0,   -1.0,    1.0,
3626        -1.0,    1.0,    0.0,
3627         1.0,    1.0,    1.0
3628     };
3629
3630     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3631     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3632
3633     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3634     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3635     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3636     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3637     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3638     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3639     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3640     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3641     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3642
3643     /* Fill the depth buffer with a gradient */
3644     hr = IDirect3DDevice9_BeginScene(device);
3645     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3646     if(SUCCEEDED(hr))
3647     {
3648         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3649         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3650         hr = IDirect3DDevice9_EndScene(device);
3651         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3652     }
3653
3654     /* Now perform the actual tests. Same geometry, but with the shader */
3655     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3656     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3657     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3658     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3659     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3660     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3661
3662     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3663     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3664     hr = IDirect3DDevice9_BeginScene(device);
3665     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3666     if(SUCCEEDED(hr))
3667     {
3668         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3669         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3670
3671         hr = IDirect3DDevice9_EndScene(device);
3672         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3673     }
3674
3675     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3676     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3677     color = getPixelColor(device, 158, 240);
3678     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3679     color = getPixelColor(device, 162, 240);
3680     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3681
3682     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3683
3684     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3685     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3686     hr = IDirect3DDevice9_BeginScene(device);
3687     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3688     if(SUCCEEDED(hr))
3689     {
3690         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3691         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3692
3693         hr = IDirect3DDevice9_EndScene(device);
3694         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3695     }
3696
3697     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3698     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3699     color = getPixelColor(device, 318, 240);
3700     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3701     color = getPixelColor(device, 322, 240);
3702     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3703
3704     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3705
3706     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3707     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3708     hr = IDirect3DDevice9_BeginScene(device);
3709     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3710     if(SUCCEEDED(hr))
3711     {
3712         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3713         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3714
3715         hr = IDirect3DDevice9_EndScene(device);
3716         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3717     }
3718     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3720
3721     color = getPixelColor(device, 1, 240);
3722     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3723
3724     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3725
3726     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3727     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3728     hr = IDirect3DDevice9_BeginScene(device);
3729     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3730     if(SUCCEEDED(hr))
3731     {
3732         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3733         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3734
3735         hr = IDirect3DDevice9_EndScene(device);
3736         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3737     }
3738     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3739     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3740     color = getPixelColor(device, 318, 240);
3741     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3742     color = getPixelColor(device, 322, 240);
3743     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3744
3745     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3746
3747     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3748     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3749     hr = IDirect3DDevice9_BeginScene(device);
3750     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3751     if(SUCCEEDED(hr))
3752     {
3753         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3754         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3755
3756         hr = IDirect3DDevice9_EndScene(device);
3757         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3758     }
3759     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3761
3762     color = getPixelColor(device, 1, 240);
3763     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3764
3765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3766
3767     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3768     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3769     hr = IDirect3DDevice9_BeginScene(device);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3771     if(SUCCEEDED(hr))
3772     {
3773         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3774         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3775
3776         hr = IDirect3DDevice9_EndScene(device);
3777         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3778     }
3779     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3781
3782     color = getPixelColor(device, 638, 240);
3783     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3784
3785     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3786
3787     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3788     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3789     hr = IDirect3DDevice9_BeginScene(device);
3790     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3791     if(SUCCEEDED(hr))
3792     {
3793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3794         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3795
3796         hr = IDirect3DDevice9_EndScene(device);
3797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3798     }
3799     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3801
3802     color = getPixelColor(device, 638, 240);
3803     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3804
3805     /* Cleanup */
3806     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3808     IDirect3DPixelShader9_Release(shader);
3809
3810     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3811     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3812     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3813     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3814 }
3815
3816 static void texkill_test(IDirect3DDevice9 *device)
3817 {
3818     IDirect3DPixelShader9 *shader;
3819     HRESULT hr;
3820     DWORD color;
3821
3822     const float vertex[] = {
3823     /*                          bottom  top    right    left */
3824         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3825          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3826         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3827          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3828     };
3829
3830     DWORD shader_code_11[] = {
3831     0xffff0101,                                                             /* ps_1_1                     */
3832     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3833     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3834     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3835     0x0000ffff                                                              /* end                        */
3836     };
3837     DWORD shader_code_20[] = {
3838     0xffff0200,                                                             /* ps_2_0                     */
3839     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3840     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3841     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3842     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3843     0x0000ffff                                                              /* end                        */
3844     };
3845
3846     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3847     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3848     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3849     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3850
3851     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3852     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3853     hr = IDirect3DDevice9_BeginScene(device);
3854     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3855     if(SUCCEEDED(hr))
3856     {
3857         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3858         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3859         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3860         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3861         hr = IDirect3DDevice9_EndScene(device);
3862         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3863     }
3864     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3865     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3866     color = getPixelColor(device, 63, 46);
3867     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3868     color = getPixelColor(device, 66, 46);
3869     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3870     color = getPixelColor(device, 63, 49);
3871     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3872     color = getPixelColor(device, 66, 49);
3873     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3874
3875     color = getPixelColor(device, 578, 46);
3876     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3877     color = getPixelColor(device, 575, 46);
3878     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3879     color = getPixelColor(device, 578, 49);
3880     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3881     color = getPixelColor(device, 575, 49);
3882     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3883
3884     color = getPixelColor(device, 63, 430);
3885     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3886     color = getPixelColor(device, 63, 433);
3887     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3888     color = getPixelColor(device, 66, 433);
3889     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3890     color = getPixelColor(device, 66, 430);
3891     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3892
3893     color = getPixelColor(device, 578, 430);
3894     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3895     color = getPixelColor(device, 578, 433);
3896     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3897     color = getPixelColor(device, 575, 433);
3898     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3899     color = getPixelColor(device, 575, 430);
3900     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3901
3902     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3903     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3904     IDirect3DPixelShader9_Release(shader);
3905
3906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3907     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3908     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3909     if(FAILED(hr)) {
3910         skip("Failed to create 2.0 test shader, most likely not supported\n");
3911         return;
3912     }
3913
3914     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3915     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3916     hr = IDirect3DDevice9_BeginScene(device);
3917     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3918     if(SUCCEEDED(hr))
3919     {
3920         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3921         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3922         hr = IDirect3DDevice9_EndScene(device);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3924     }
3925     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3926
3927     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3928     color = getPixelColor(device, 63, 46);
3929     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3930     color = getPixelColor(device, 66, 46);
3931     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3932     color = getPixelColor(device, 63, 49);
3933     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3934     color = getPixelColor(device, 66, 49);
3935     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3936
3937     color = getPixelColor(device, 578, 46);
3938     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3939     color = getPixelColor(device, 575, 46);
3940     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3941     color = getPixelColor(device, 578, 49);
3942     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3943     color = getPixelColor(device, 575, 49);
3944     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3945
3946     color = getPixelColor(device, 63, 430);
3947     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3948     color = getPixelColor(device, 63, 433);
3949     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3950     color = getPixelColor(device, 66, 433);
3951     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3952     color = getPixelColor(device, 66, 430);
3953     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3954
3955     color = getPixelColor(device, 578, 430);
3956     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3957     color = getPixelColor(device, 578, 433);
3958     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3959     color = getPixelColor(device, 575, 433);
3960     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3961     color = getPixelColor(device, 575, 430);
3962     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3963
3964     /* Cleanup */
3965     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3966     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3967     IDirect3DPixelShader9_Release(shader);
3968 }
3969
3970 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3971 {
3972     IDirect3D9 *d3d9;
3973     HRESULT hr;
3974     IDirect3DTexture9 *texture;
3975     IDirect3DPixelShader9 *shader;
3976     IDirect3DPixelShader9 *shader2;
3977     D3DLOCKED_RECT lr;
3978     DWORD color;
3979     DWORD shader_code[] = {
3980         0xffff0101,                             /* ps_1_1       */
3981         0x00000042, 0xb00f0000,                 /* tex t0       */
3982         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3983         0x0000ffff                              /* end          */
3984     };
3985     DWORD shader_code2[] = {
3986         0xffff0101,                             /* ps_1_1       */
3987         0x00000042, 0xb00f0000,                 /* tex t0       */
3988         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3989         0x0000ffff                              /* end          */
3990     };
3991
3992     float quad[] = {
3993        -1.0,   -1.0,   0.1,     0.5,    0.5,
3994         1.0,   -1.0,   0.1,     0.5,    0.5,
3995        -1.0,    1.0,   0.1,     0.5,    0.5,
3996         1.0,    1.0,   0.1,     0.5,    0.5,
3997     };
3998
3999     memset(&lr, 0, sizeof(lr));
4000     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4001     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4002                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4003     IDirect3D9_Release(d3d9);
4004     if(FAILED(hr)) {
4005         skip("No D3DFMT_X8L8V8U8 support\n");
4006     };
4007
4008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4009     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4010
4011     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4012     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4013     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4014     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4015     *((DWORD *) lr.pBits) = 0x11ca3141;
4016     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4017     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4018
4019     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4020     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4021     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4022     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4023
4024     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4025     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4026     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4027     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4028     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4030
4031     hr = IDirect3DDevice9_BeginScene(device);
4032     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4033     if(SUCCEEDED(hr))
4034     {
4035         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4036         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4037
4038         hr = IDirect3DDevice9_EndScene(device);
4039         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4040     }
4041     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4042     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4043     color = getPixelColor(device, 578, 430);
4044     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4045        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4046
4047     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4048     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4049     hr = IDirect3DDevice9_BeginScene(device);
4050     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4051     if(SUCCEEDED(hr))
4052     {
4053         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4054         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4055
4056         hr = IDirect3DDevice9_EndScene(device);
4057         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4058     }
4059     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4060     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4061     color = getPixelColor(device, 578, 430);
4062     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4063
4064     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4065     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4066     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4067     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4068     IDirect3DPixelShader9_Release(shader);
4069     IDirect3DPixelShader9_Release(shader2);
4070     IDirect3DTexture9_Release(texture);
4071 }
4072
4073 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4074 {
4075     HRESULT hr;
4076     IDirect3D9 *d3d;
4077     IDirect3DTexture9 *texture = NULL;
4078     IDirect3DSurface9 *surface;
4079     DWORD color;
4080     const RECT r1 = {256, 256, 512, 512};
4081     const RECT r2 = {512, 256, 768, 512};
4082     const RECT r3 = {256, 512, 512, 768};
4083     const RECT r4 = {512, 512, 768, 768};
4084     unsigned int x, y;
4085     D3DLOCKED_RECT lr;
4086     memset(&lr, 0, sizeof(lr));
4087
4088     IDirect3DDevice9_GetDirect3D(device, &d3d);
4089     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4090        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4091         skip("No autogenmipmap support\n");
4092         IDirect3D9_Release(d3d);
4093         return;
4094     }
4095     IDirect3D9_Release(d3d);
4096
4097     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4098     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4099
4100     /* Make the mipmap big, so that a smaller mipmap is used
4101      */
4102     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4103                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4105
4106     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4107     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4108     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4109     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4110     for(y = 0; y < 1024; y++) {
4111         for(x = 0; x < 1024; x++) {
4112             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4113             POINT pt;
4114
4115             pt.x = x;
4116             pt.y = y;
4117             if(PtInRect(&r1, pt)) {
4118                 *dst = 0xffff0000;
4119             } else if(PtInRect(&r2, pt)) {
4120                 *dst = 0xff00ff00;
4121             } else if(PtInRect(&r3, pt)) {
4122                 *dst = 0xff0000ff;
4123             } else if(PtInRect(&r4, pt)) {
4124                 *dst = 0xff000000;
4125             } else {
4126                 *dst = 0xffffffff;
4127             }
4128         }
4129     }
4130     hr = IDirect3DSurface9_UnlockRect(surface);
4131     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4132     IDirect3DSurface9_Release(surface);
4133
4134     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4135     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4136     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4137     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4138
4139     hr = IDirect3DDevice9_BeginScene(device);
4140     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4141     if(SUCCEEDED(hr)) {
4142         const float quad[] =  {
4143            -0.5,   -0.5,    0.1,    0.0,    0.0,
4144            -0.5,    0.5,    0.1,    0.0,    1.0,
4145             0.5,   -0.5,    0.1,    1.0,    0.0,
4146             0.5,    0.5,    0.1,    1.0,    1.0
4147         };
4148
4149         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4150         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4152         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4153         hr = IDirect3DDevice9_EndScene(device);
4154         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4155     }
4156     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4157     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4158     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4159     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4160     IDirect3DTexture9_Release(texture);
4161
4162     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4163     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4164     color = getPixelColor(device, 200, 200);
4165     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4166     color = getPixelColor(device, 280, 200);
4167     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4168     color = getPixelColor(device, 360, 200);
4169     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4170     color = getPixelColor(device, 440, 200);
4171     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4172     color = getPixelColor(device, 200, 270);
4173     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4174     color = getPixelColor(device, 280, 270);
4175     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4176     color = getPixelColor(device, 360, 270);
4177     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4178     color = getPixelColor(device, 440, 270);
4179     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4180 }
4181
4182 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4183 {
4184     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4185     IDirect3DVertexDeclaration9 *decl;
4186     HRESULT hr;
4187     DWORD color;
4188     DWORD shader_code_11[] =  {
4189         0xfffe0101,                                         /* vs_1_1           */
4190         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4191         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4192         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4193         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4194         0x0000ffff                                          /* end              */
4195     };
4196     DWORD shader_code_11_2[] =  {
4197         0xfffe0101,                                         /* vs_1_1           */
4198         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4199         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4200         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4201         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4202         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4203         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4204         0x0000ffff                                          /* end              */
4205     };
4206     DWORD shader_code_20[] =  {
4207         0xfffe0200,                                         /* vs_2_0           */
4208         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4209         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4210         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4211         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4212         0x0000ffff                                          /* end              */
4213     };
4214     DWORD shader_code_20_2[] =  {
4215         0xfffe0200,                                         /* vs_2_0           */
4216         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4217         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4218         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4219         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4220         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4221         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4222         0x0000ffff                                          /* end              */
4223     };
4224     static const D3DVERTEXELEMENT9 decl_elements[] = {
4225         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4226         D3DDECL_END()
4227     };
4228     float quad1[] = {
4229         -1.0,   -1.0,   0.1,
4230          0.0,   -1.0,   0.1,
4231         -1.0,    0.0,   0.1,
4232          0.0,    0.0,   0.1
4233     };
4234     float quad2[] = {
4235          0.0,   -1.0,   0.1,
4236          1.0,   -1.0,   0.1,
4237          0.0,    0.0,   0.1,
4238          1.0,    0.0,   0.1
4239     };
4240     float quad3[] = {
4241          0.0,    0.0,   0.1,
4242          1.0,    0.0,   0.1,
4243          0.0,    1.0,   0.1,
4244          1.0,    1.0,   0.1
4245     };
4246     float quad4[] = {
4247         -1.0,    0.0,   0.1,
4248          0.0,    0.0,   0.1,
4249         -1.0,    1.0,   0.1,
4250          0.0,    1.0,   0.1
4251     };
4252     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4253     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4254
4255     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4256     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4257
4258     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4259     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4260     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4262     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4263     if(FAILED(hr)) shader_20 = NULL;
4264     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4265     if(FAILED(hr)) shader_20_2 = NULL;
4266     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4268
4269     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4270     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4271     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4272     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4273     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4274     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4275
4276     hr = IDirect3DDevice9_BeginScene(device);
4277     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4278     if(SUCCEEDED(hr))
4279     {
4280         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4281         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4283         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4284
4285         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4286         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4287         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4288         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4289
4290         if(shader_20) {
4291             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4292             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4293             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4294             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4295         }
4296
4297         if(shader_20_2) {
4298             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4299             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4300             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4301             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4302         }
4303
4304         hr = IDirect3DDevice9_EndScene(device);
4305         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4306     }
4307     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4308     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4309
4310     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4311     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4312     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4313     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4314
4315     color = getPixelColor(device, 160, 360);
4316     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4317        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4318     color = getPixelColor(device, 480, 360);
4319     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4320        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4321     if(shader_20) {
4322         color = getPixelColor(device, 160, 120);
4323         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4324            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4325     }
4326     if(shader_20_2) {
4327         color = getPixelColor(device, 480, 120);
4328         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4330     }
4331
4332     IDirect3DVertexDeclaration9_Release(decl);
4333     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4334     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4335     IDirect3DVertexShader9_Release(shader_11_2);
4336     IDirect3DVertexShader9_Release(shader_11);
4337 }
4338
4339 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4340 {
4341     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4342     HRESULT hr;
4343     DWORD color;
4344     DWORD shader_code_11[] =  {
4345         0xffff0101,                                         /* ps_1_1           */
4346         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4347         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4348         0x0000ffff                                          /* end              */
4349     };
4350     DWORD shader_code_12[] =  {
4351         0xffff0102,                                         /* ps_1_2           */
4352         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4353         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4354         0x0000ffff                                          /* end              */
4355     };
4356     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4357      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4358      * During development of this test, 1.3 shaders were verified too
4359      */
4360     DWORD shader_code_14[] =  {
4361         0xffff0104,                                         /* ps_1_4           */
4362         /* Try to make one constant local. It gets clamped too, although the binary contains
4363          * the bigger numbers
4364          */
4365         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4366         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4367         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4368         0x0000ffff                                          /* end              */
4369     };
4370     DWORD shader_code_20[] =  {
4371         0xffff0200,                                         /* ps_2_0           */
4372         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4373         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4374         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4375         0x0000ffff                                          /* end              */
4376     };
4377     float quad1[] = {
4378         -1.0,   -1.0,   0.1,
4379          0.0,   -1.0,   0.1,
4380         -1.0,    0.0,   0.1,
4381          0.0,    0.0,   0.1
4382     };
4383     float quad2[] = {
4384          0.0,   -1.0,   0.1,
4385          1.0,   -1.0,   0.1,
4386          0.0,    0.0,   0.1,
4387          1.0,    0.0,   0.1
4388     };
4389     float quad3[] = {
4390          0.0,    0.0,   0.1,
4391          1.0,    0.0,   0.1,
4392          0.0,    1.0,   0.1,
4393          1.0,    1.0,   0.1
4394     };
4395     float quad4[] = {
4396         -1.0,    0.0,   0.1,
4397          0.0,    0.0,   0.1,
4398         -1.0,    1.0,   0.1,
4399          0.0,    1.0,   0.1
4400     };
4401     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4402     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4403
4404     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4405     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4406
4407     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4408     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4409     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4410     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4411     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4412     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4413     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4414     if(FAILED(hr)) shader_20 = NULL;
4415
4416     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4417     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4418     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4419     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4420     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4421     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4422
4423     hr = IDirect3DDevice9_BeginScene(device);
4424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4425     if(SUCCEEDED(hr))
4426     {
4427         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4428         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4429         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4430         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4431
4432         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4433         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4435         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4436
4437         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4438         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4439         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4440         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4441
4442         if(shader_20) {
4443             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4444             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4445             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4446             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4447         }
4448
4449         hr = IDirect3DDevice9_EndScene(device);
4450         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4451     }
4452     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4453     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4454
4455     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4456     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4457
4458     color = getPixelColor(device, 160, 360);
4459     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4460        "quad 1 has color %08x, expected 0x00808000\n", color);
4461     color = getPixelColor(device, 480, 360);
4462     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4463        "quad 2 has color %08x, expected 0x00808000\n", color);
4464     color = getPixelColor(device, 480, 120);
4465     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4466        "quad 3 has color %08x, expected 0x00808000\n", color);
4467     if(shader_20) {
4468         color = getPixelColor(device, 160, 120);
4469         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4470            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4471     }
4472
4473     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4474     IDirect3DPixelShader9_Release(shader_14);
4475     IDirect3DPixelShader9_Release(shader_12);
4476     IDirect3DPixelShader9_Release(shader_11);
4477 }
4478
4479 static void dp2add_ps_test(IDirect3DDevice9 *device)
4480 {
4481     IDirect3DPixelShader9 *shader_dp2add = NULL;
4482     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4483     HRESULT hr;
4484     DWORD color;
4485
4486     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4487      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4488      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4489      * r0 first.
4490      * The result here for the r,g,b components should be roughly 0.5:
4491      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4492     static const DWORD shader_code_dp2add[] =  {
4493         0xffff0200,                                                             /* ps_2_0                       */
4494         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4495
4496         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4497         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4498
4499         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4500         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4501         0x0000ffff                                                              /* end                          */
4502     };
4503
4504     /* Test the _sat modifier, too.  Result here should be:
4505      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4506      *      _SAT: ==> 1.0
4507      *   ADD: (1.0 + -0.5) = 0.5
4508      */
4509     static const DWORD shader_code_dp2add_sat[] =  {
4510         0xffff0200,                                                             /* ps_2_0                           */
4511         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4512
4513         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4514         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4515         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4516
4517         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4518         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4519         0x0000ffff                                                              /* end                              */
4520     };
4521
4522     const float quad[] = {
4523         -1.0,   -1.0,   0.1,
4524          1.0,   -1.0,   0.1,
4525         -1.0,    1.0,   0.1,
4526          1.0,    1.0,   0.1
4527     };
4528
4529
4530     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4531     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4532
4533     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4534     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4535
4536     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4537     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4538
4539     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4541
4542     if (shader_dp2add) {
4543
4544         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4545         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4546
4547         hr = IDirect3DDevice9_BeginScene(device);
4548         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4549         if(SUCCEEDED(hr))
4550         {
4551             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4552             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4553
4554             hr = IDirect3DDevice9_EndScene(device);
4555             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4556         }
4557         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4558         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4559
4560         color = getPixelColor(device, 360, 240);
4561         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4562
4563         IDirect3DPixelShader9_Release(shader_dp2add);
4564     } else {
4565         skip("dp2add shader creation failed\n");
4566     }
4567
4568     if (shader_dp2add_sat) {
4569
4570         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4571         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4572
4573         hr = IDirect3DDevice9_BeginScene(device);
4574         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4575         if(SUCCEEDED(hr))
4576         {
4577             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4578             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4579
4580             hr = IDirect3DDevice9_EndScene(device);
4581             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4582         }
4583         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4584         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4585
4586         color = getPixelColor(device, 360, 240);
4587         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4588
4589         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4590     } else {
4591         skip("dp2add shader creation failed\n");
4592     }
4593
4594     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4595     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4596 }
4597
4598 static void cnd_test(IDirect3DDevice9 *device)
4599 {
4600     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4601     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4602     HRESULT hr;
4603     DWORD color;
4604     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4605      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4606      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4607      */
4608     DWORD shader_code_11[] =  {
4609         0xffff0101,                                                                 /* ps_1_1               */
4610         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4611         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4612         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4613         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4614         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4615         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4616         0x0000ffff                                                                  /* end                  */
4617     };
4618     DWORD shader_code_12[] =  {
4619         0xffff0102,                                                                 /* ps_1_2               */
4620         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4621         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4622         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4623         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4624         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4625         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4626         0x0000ffff                                                                  /* end                  */
4627     };
4628     DWORD shader_code_13[] =  {
4629         0xffff0103,                                                                 /* ps_1_3               */
4630         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4631         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4632         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4633         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4634         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4635         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4636         0x0000ffff                                                                  /* end                  */
4637     };
4638     DWORD shader_code_14[] =  {
4639         0xffff0104,                                                                 /* ps_1_3               */
4640         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4641         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4642         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4643         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4644         0x0000ffff                                                                  /* end                  */
4645     };
4646
4647     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4648      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4649      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4650      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4651      * native CreatePixelShader returns an error.
4652      *
4653      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4654      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4655      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4656      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4657      */
4658     DWORD shader_code_11_coissue[] =  {
4659         0xffff0101,                                                             /* ps_1_1                   */
4660         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4661         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4662         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4663         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4664         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4665         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4666         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4667         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4668         /* 0x40000000 = D3DSI_COISSUE */
4669         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4670         0x0000ffff                                                              /* end                      */
4671     };
4672     DWORD shader_code_12_coissue[] =  {
4673         0xffff0102,                                                             /* ps_1_2                   */
4674         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4675         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4676         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4677         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4678         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4679         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4680         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4681         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4682         /* 0x40000000 = D3DSI_COISSUE */
4683         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4684         0x0000ffff                                                              /* end                      */
4685     };
4686     DWORD shader_code_13_coissue[] =  {
4687         0xffff0103,                                                             /* ps_1_3                   */
4688         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4689         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4690         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4691         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4692         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4693         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4694         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4695         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4696         /* 0x40000000 = D3DSI_COISSUE */
4697         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4698         0x0000ffff                                                              /* end                      */
4699     };
4700     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4701      * compare against 0.5
4702      */
4703     DWORD shader_code_14_coissue[] =  {
4704         0xffff0104,                                                             /* ps_1_4                   */
4705         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4706         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4707         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4708         /* 0x40000000 = D3DSI_COISSUE */
4709         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4710         0x0000ffff                                                              /* end                      */
4711     };
4712     float quad1[] = {
4713         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4714          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4715         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4716          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4717     };
4718     float quad2[] = {
4719          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4720          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4721          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4722          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4723     };
4724     float quad3[] = {
4725          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4726          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4727          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4728          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4729     };
4730     float quad4[] = {
4731         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4732          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4733         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4734          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4735     };
4736     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4737     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4738     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4739     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4740
4741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4742     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4743
4744     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4746     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4747     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4748     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4749     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4750     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4752     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4754     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4755     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4756     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4758     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4760
4761     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4762     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4763     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4764     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4765     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4767
4768     hr = IDirect3DDevice9_BeginScene(device);
4769     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4770     if(SUCCEEDED(hr))
4771     {
4772         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4773         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4774         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4775         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4776
4777         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4778         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4780         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4781
4782         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4784         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4785         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4786
4787         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4788         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4789         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4790         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791
4792         hr = IDirect3DDevice9_EndScene(device);
4793         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4794     }
4795     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4796     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4797
4798     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4799     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4800
4801     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4802     color = getPixelColor(device, 158, 118);
4803     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4804     color = getPixelColor(device, 162, 118);
4805     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4806     color = getPixelColor(device, 158, 122);
4807     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4808     color = getPixelColor(device, 162, 122);
4809     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4810
4811     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4812     color = getPixelColor(device, 158, 358);
4813     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4814     color = getPixelColor(device, 162, 358);
4815     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4816         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4817     color = getPixelColor(device, 158, 362);
4818     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4819     color = getPixelColor(device, 162, 362);
4820     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4821         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4822
4823     /* 1.2 shader */
4824     color = getPixelColor(device, 478, 358);
4825     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4826     color = getPixelColor(device, 482, 358);
4827     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4828         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4829     color = getPixelColor(device, 478, 362);
4830     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4831     color = getPixelColor(device, 482, 362);
4832     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4833         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4834
4835     /* 1.3 shader */
4836     color = getPixelColor(device, 478, 118);
4837     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4838     color = getPixelColor(device, 482, 118);
4839     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4840         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4841     color = getPixelColor(device, 478, 122);
4842     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4843     color = getPixelColor(device, 482, 122);
4844     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4845         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4846
4847     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4848     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4849     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4850     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4851     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4852     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4853
4854     hr = IDirect3DDevice9_BeginScene(device);
4855     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4856     if(SUCCEEDED(hr))
4857     {
4858         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4859         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4860         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4861         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4862
4863         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4864         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4866         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4867
4868         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4869         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4870         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4871         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4872
4873         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4874         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4875         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4876         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4877
4878         hr = IDirect3DDevice9_EndScene(device);
4879         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4880     }
4881     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4882     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4883
4884     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4885      * that we swapped the values in c1 and c2 to make the other tests return some color
4886      */
4887     color = getPixelColor(device, 158, 118);
4888     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4889     color = getPixelColor(device, 162, 118);
4890     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4891     color = getPixelColor(device, 158, 122);
4892     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4893     color = getPixelColor(device, 162, 122);
4894     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4895
4896     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4897     color = getPixelColor(device, 158, 358);
4898     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4899         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4900     color = getPixelColor(device, 162, 358);
4901     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4902         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4903     color = getPixelColor(device, 158, 362);
4904     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4905         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4906     color = getPixelColor(device, 162, 362);
4907     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4908         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4909
4910     /* 1.2 shader */
4911     color = getPixelColor(device, 478, 358);
4912     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4913         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4914     color = getPixelColor(device, 482, 358);
4915     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4916         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4917     color = getPixelColor(device, 478, 362);
4918     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4919         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4920     color = getPixelColor(device, 482, 362);
4921     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4922         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4923
4924     /* 1.3 shader */
4925     color = getPixelColor(device, 478, 118);
4926     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4927         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4928     color = getPixelColor(device, 482, 118);
4929     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4930         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4931     color = getPixelColor(device, 478, 122);
4932     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4933         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4934     color = getPixelColor(device, 482, 122);
4935     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4936         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4937
4938     IDirect3DPixelShader9_Release(shader_14_coissue);
4939     IDirect3DPixelShader9_Release(shader_13_coissue);
4940     IDirect3DPixelShader9_Release(shader_12_coissue);
4941     IDirect3DPixelShader9_Release(shader_11_coissue);
4942     IDirect3DPixelShader9_Release(shader_14);
4943     IDirect3DPixelShader9_Release(shader_13);
4944     IDirect3DPixelShader9_Release(shader_12);
4945     IDirect3DPixelShader9_Release(shader_11);
4946 }
4947
4948 static void nested_loop_test(IDirect3DDevice9 *device) {
4949     const DWORD shader_code[] = {
4950         0xffff0300,                                                             /* ps_3_0               */
4951         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4952         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4953         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4954         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4955         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4956         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4957         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4958         0x0000001d,                                                             /* endloop              */
4959         0x0000001d,                                                             /* endloop              */
4960         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4961         0x0000ffff                                                              /* end                  */
4962     };
4963     IDirect3DPixelShader9 *shader;
4964     HRESULT hr;
4965     DWORD color;
4966     const float quad[] = {
4967         -1.0,   -1.0,   0.1,
4968          1.0,   -1.0,   0.1,
4969         -1.0,    1.0,   0.1,
4970          1.0,    1.0,   0.1
4971     };
4972
4973     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4974     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4975     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4976     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4977     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4978     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4979     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4980     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4981
4982     hr = IDirect3DDevice9_BeginScene(device);
4983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4984     if(SUCCEEDED(hr))
4985     {
4986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4988         hr = IDirect3DDevice9_EndScene(device);
4989         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4990     }
4991     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4992     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4993
4994     color = getPixelColor(device, 360, 240);
4995     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4996        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4997
4998     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4999     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
5000     IDirect3DPixelShader9_Release(shader);
5001 }
5002
5003 struct varying_test_struct
5004 {
5005     const DWORD             *shader_code;
5006     IDirect3DPixelShader9   *shader;
5007     DWORD                   color, color_rhw;
5008     const char              *name;
5009     BOOL                    todo, todo_rhw;
5010 };
5011
5012 struct hugeVertex
5013 {
5014     float pos_x,        pos_y,      pos_z,      rhw;
5015     float weight_1,     weight_2,   weight_3,   weight_4;
5016     float index_1,      index_2,    index_3,    index_4;
5017     float normal_1,     normal_2,   normal_3,   normal_4;
5018     float fog_1,        fog_2,      fog_3,      fog_4;
5019     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5020     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5021     float binormal_1,   binormal_2, binormal_3, binormal_4;
5022     float depth_1,      depth_2,    depth_3,    depth_4;
5023     DWORD diffuse, specular;
5024 };
5025
5026 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5027     /* dcl_position: fails to compile */
5028     const DWORD blendweight_code[] = {
5029         0xffff0300,                             /* ps_3_0                   */
5030         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5031         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5032         0x0000ffff                              /* end                      */
5033     };
5034     const DWORD blendindices_code[] = {
5035         0xffff0300,                             /* ps_3_0                   */
5036         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5037         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5038         0x0000ffff                              /* end                      */
5039     };
5040     const DWORD normal_code[] = {
5041         0xffff0300,                             /* ps_3_0                   */
5042         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5043         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5044         0x0000ffff                              /* end                      */
5045     };
5046     /* psize: fails? */
5047     const DWORD texcoord0_code[] = {
5048         0xffff0300,                             /* ps_3_0                   */
5049         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5050         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5051         0x0000ffff                              /* end                      */
5052     };
5053     const DWORD tangent_code[] = {
5054         0xffff0300,                             /* ps_3_0                   */
5055         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5056         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5057         0x0000ffff                              /* end                      */
5058     };
5059     const DWORD binormal_code[] = {
5060         0xffff0300,                             /* ps_3_0                   */
5061         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5062         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5063         0x0000ffff                              /* end                      */
5064     };
5065     /* tessfactor: fails */
5066     /* positiont: fails */
5067     const DWORD color_code[] = {
5068         0xffff0300,                             /* ps_3_0                   */
5069         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5070         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5071         0x0000ffff                              /* end                      */
5072     };
5073     const DWORD fog_code[] = {
5074         0xffff0300,                             /* ps_3_0                   */
5075         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5076         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5077         0x0000ffff                              /* end                      */
5078     };
5079     const DWORD depth_code[] = {
5080         0xffff0300,                             /* ps_3_0                   */
5081         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5082         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5083         0x0000ffff                              /* end                      */
5084     };
5085     const DWORD specular_code[] = {
5086         0xffff0300,                             /* ps_3_0                   */
5087         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5088         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5089         0x0000ffff                              /* end                      */
5090     };
5091     /* sample: fails */
5092
5093     struct varying_test_struct tests[] = {
5094        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5095        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5096        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5097        /* Why does dx not forward the texcoord? */
5098        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5099        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5100        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5101        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5102        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5103        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5104        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5105     };
5106     /* Declare a monster vertex type :-) */
5107     static const D3DVERTEXELEMENT9 decl_elements[] = {
5108         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5109         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5110         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5111         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5112         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5113         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5114         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5115         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5116         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5117         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5118         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5119         D3DDECL_END()
5120     };
5121     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5122         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5123         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5124         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5125         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5126         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5127         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5128         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5129         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5130         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5131         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5132         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5133         D3DDECL_END()
5134     };
5135     struct hugeVertex data[4] = {
5136         {
5137             -1.0,   -1.0,   0.1,    1.0,
5138              0.1,    0.1,   0.1,    0.1,
5139              0.2,    0.2,   0.2,    0.2,
5140              0.3,    0.3,   0.3,    0.3,
5141              0.4,    0.4,   0.4,    0.4,
5142              0.50,   0.55,  0.55,   0.55,
5143              0.6,    0.6,   0.6,    0.7,
5144              0.7,    0.7,   0.7,    0.6,
5145              0.8,    0.8,   0.8,    0.8,
5146              0xe6e6e6e6, /* 0.9 * 256 */
5147              0x224488ff  /* Nothing special */
5148         },
5149         {
5150              1.0,   -1.0,   0.1,    1.0,
5151              0.1,    0.1,   0.1,    0.1,
5152              0.2,    0.2,   0.2,    0.2,
5153              0.3,    0.3,   0.3,    0.3,
5154              0.4,    0.4,   0.4,    0.4,
5155              0.50,   0.55,  0.55,   0.55,
5156              0.6,    0.6,   0.6,    0.7,
5157              0.7,    0.7,   0.7,    0.6,
5158              0.8,    0.8,   0.8,    0.8,
5159              0xe6e6e6e6, /* 0.9 * 256 */
5160              0x224488ff /* Nothing special */
5161         },
5162         {
5163             -1.0,    1.0,   0.1,    1.0,
5164              0.1,    0.1,   0.1,    0.1,
5165              0.2,    0.2,   0.2,    0.2,
5166              0.3,    0.3,   0.3,    0.3,
5167              0.4,    0.4,   0.4,    0.4,
5168              0.50,   0.55,  0.55,   0.55,
5169              0.6,    0.6,   0.6,    0.7,
5170              0.7,    0.7,   0.7,    0.6,
5171              0.8,    0.8,   0.8,    0.8,
5172              0xe6e6e6e6, /* 0.9 * 256 */
5173              0x224488ff /* Nothing special */
5174         },
5175         {
5176              1.0,    1.0,   0.1,    1.0,
5177              0.1,    0.1,   0.1,    0.1,
5178              0.2,    0.2,   0.2,    0.2,
5179              0.3,    0.3,   0.3,    0.3,
5180              0.4,    0.4,   0.4,    0.4,
5181              0.50,   0.55,  0.55,   0.55,
5182              0.6,    0.6,   0.6,    0.7,
5183              0.7,    0.7,   0.7,    0.6,
5184              0.8,    0.8,   0.8,    0.8,
5185              0xe6e6e6e6, /* 0.9 * 256 */
5186              0x224488ff /* Nothing special */
5187         },
5188     };
5189     struct hugeVertex data2[4];
5190     IDirect3DVertexDeclaration9 *decl;
5191     IDirect3DVertexDeclaration9 *decl2;
5192     HRESULT hr;
5193     unsigned int i;
5194     DWORD color, r, g, b, r_e, g_e, b_e;
5195     BOOL drawok;
5196
5197     memcpy(data2, data, sizeof(data2));
5198     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5199     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5200     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5201     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5202
5203     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5205     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5207     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5208     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5209
5210     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5211     {
5212         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5213         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5214            tests[i].name, DXGetErrorString9(hr));
5215     }
5216
5217     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5218     {
5219         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5220         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5221
5222         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5223         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5224
5225         hr = IDirect3DDevice9_BeginScene(device);
5226         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5227         drawok = FALSE;
5228         if(SUCCEEDED(hr))
5229         {
5230             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5231             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5232             drawok = SUCCEEDED(hr);
5233             hr = IDirect3DDevice9_EndScene(device);
5234             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5235         }
5236         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5237         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5238
5239         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5240          * the failure and do not check the color if it failed
5241          */
5242         if(!drawok) {
5243             continue;
5244         }
5245
5246         color = getPixelColor(device, 360, 240);
5247         r = color & 0x00ff0000 >> 16;
5248         g = color & 0x0000ff00 >>  8;
5249         b = color & 0x000000ff;
5250         r_e = tests[i].color & 0x00ff0000 >> 16;
5251         g_e = tests[i].color & 0x0000ff00 >>  8;
5252         b_e = tests[i].color & 0x000000ff;
5253
5254         if(tests[i].todo) {
5255             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5256                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5257                          tests[i].name, color, tests[i].color);
5258         } else {
5259             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5260                "Test %s returned color 0x%08x, expected 0x%08x\n",
5261                tests[i].name, color, tests[i].color);
5262         }
5263     }
5264
5265     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5266     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5267     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5268     {
5269         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5270         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5271
5272         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5273         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5274
5275         hr = IDirect3DDevice9_BeginScene(device);
5276         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5277         if(SUCCEEDED(hr))
5278         {
5279             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5280             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5281             hr = IDirect3DDevice9_EndScene(device);
5282             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5283         }
5284         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5285         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5286
5287         color = getPixelColor(device, 360, 240);
5288         r = color & 0x00ff0000 >> 16;
5289         g = color & 0x0000ff00 >>  8;
5290         b = color & 0x000000ff;
5291         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5292         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5293         b_e = tests[i].color_rhw & 0x000000ff;
5294
5295         if(tests[i].todo_rhw) {
5296             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5297              * pipeline
5298              */
5299             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5300                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5301                          tests[i].name, color, tests[i].color_rhw);
5302         } else {
5303             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5304                "Test %s returned color 0x%08x, expected 0x%08x\n",
5305                tests[i].name, color, tests[i].color_rhw);
5306         }
5307     }
5308
5309     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5310     {
5311         IDirect3DPixelShader9_Release(tests[i].shader);
5312     }
5313
5314     IDirect3DVertexDeclaration9_Release(decl2);
5315     IDirect3DVertexDeclaration9_Release(decl);
5316 }
5317
5318 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5319     static const DWORD ps_code[] = {
5320     0xffff0300,                                                             /* ps_3_0                       */
5321     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5322     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5323     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5324     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5325     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5326     0x0200001f, 0x80000003, 0x900f0006,
5327     0x0200001f, 0x80000006, 0x900f0007,
5328     0x0200001f, 0x80000001, 0x900f0008,
5329     0x0200001f, 0x8000000c, 0x900f0009,
5330
5331     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5332     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5333     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5334     0x0000001d,                                                             /* endloop                      */
5335     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5336     0x0000ffff                                                              /* end                          */
5337     };
5338     static const DWORD vs_1_code[] = {
5339     0xfffe0101,                                                             /* vs_1_1                       */
5340     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5341     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5342     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5343     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5344     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5345     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5346     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5347     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5348     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5349     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5350     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5351     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5352     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5353     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5354     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5355     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5356     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5357     0x0000ffff
5358     };
5359     DWORD vs_2_code[] = {
5360     0xfffe0200,                                                             /* vs_2_0                       */
5361     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5362     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
5363     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0   */
5364     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0   */
5365     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5366     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5367     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5368     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5369     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5370     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5371     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5372     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5373     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5374     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5375     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5376     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5377     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5378     0x0000ffff                                                              /* end                          */
5379     };
5380     /* TODO: Define normal, tangent, blendweight and depth here */
5381     static const DWORD vs_3_code[] = {
5382     0xfffe0300,                                                             /* vs_3_0                       */
5383     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5384     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5385     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5386     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5387     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5388     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5389     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5390     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5391     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5392     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5393     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5394     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5395     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5396     0x0000ffff                                                              /* end                          */
5397     };
5398     float quad1[] =  {
5399         -1.0,   -1.0,   0.1,
5400          0.0,   -1.0,   0.1,
5401         -1.0,    0.0,   0.1,
5402          0.0,    0.0,   0.1
5403     };
5404     float quad2[] =  {
5405          0.0,   -1.0,   0.1,
5406          1.0,   -1.0,   0.1,
5407          0.0,    0.0,   0.1,
5408          1.0,    0.0,   0.1
5409     };
5410     float quad3[] =  {
5411         -1.0,    0.0,   0.1,
5412          0.0,    0.0,   0.1,
5413         -1.0,    1.0,   0.1,
5414          0.0,    1.0,   0.1
5415     };
5416
5417     HRESULT hr;
5418     DWORD color;
5419     IDirect3DPixelShader9 *pixelshader = NULL;
5420     IDirect3DVertexShader9 *vs_1_shader = NULL;
5421     IDirect3DVertexShader9 *vs_2_shader = NULL;
5422     IDirect3DVertexShader9 *vs_3_shader = NULL;
5423
5424     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5425
5426     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5427     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5428     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5429     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5430     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5431     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5432     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5433     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5434     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5435     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5436     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5437
5438     hr = IDirect3DDevice9_BeginScene(device);
5439     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5440     if(SUCCEEDED(hr))
5441     {
5442         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5443         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5444         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5445         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5446
5447         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5448         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5450         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5451
5452         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5453         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5454         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5455         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5456
5457         hr = IDirect3DDevice9_EndScene(device);
5458         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5459     }
5460     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5461     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5462
5463     color = getPixelColor(device, 160, 120);
5464     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5465        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5466        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5467        "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5468     color = getPixelColor(device, 160, 360);
5469     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5470        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5471        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5472        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5473     color = getPixelColor(device, 480, 360);
5474     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5475        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5476        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5477        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5478
5479     /* cleanup */
5480     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5481     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5482     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5483     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5484     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5485     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5486     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5487     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5488 }
5489
5490 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5491     static const DWORD vs_code[] = {
5492     0xfffe0300,                                                             /* vs_3_0                       */
5493     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5494     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5495     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5496     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5497     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5498     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5499     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5500     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5501     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5502     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5503     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5504     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5505     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5506
5507     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5508     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5509     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5510     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5511     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5512     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5513     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5514     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5515     0x0000ffff                                                              /* end                          */
5516     };
5517     static const DWORD ps_1_code[] = {
5518     0xffff0104,                                                             /* ps_1_4                       */
5519     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5520     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5521     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5522     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5523     0x0000ffff                                                              /* end                          */
5524     };
5525     static const DWORD ps_2_code[] = {
5526     0xffff0200,                                                             /* ps_2_0                       */
5527     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5528     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5529     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5530
5531     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5532     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5533     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5534     0x0000ffff                                                              /* end                          */
5535     };
5536     static const DWORD ps_3_code[] = {
5537     0xffff0300,                                                             /* ps_3_0                       */
5538     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5539     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5540     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5541
5542     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5543     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5544     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5545     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5546     0x0000ffff                                                              /* end                          */
5547     };
5548
5549     float quad1[] =  {
5550         -1.0,   -1.0,   0.1,
5551          0.0,   -1.0,   0.1,
5552         -1.0,    0.0,   0.1,
5553          0.0,    0.0,   0.1
5554     };
5555     float quad2[] =  {
5556          0.0,   -1.0,   0.1,
5557          1.0,   -1.0,   0.1,
5558          0.0,    0.0,   0.1,
5559          1.0,    0.0,   0.1
5560     };
5561     float quad3[] =  {
5562         -1.0,    0.0,   0.1,
5563          0.0,    0.0,   0.1,
5564         -1.0,    1.0,   0.1,
5565          0.0,    1.0,   0.1
5566     };
5567     float quad4[] =  {
5568          0.0,    0.0,   0.1,
5569          1.0,    0.0,   0.1,
5570          0.0,    1.0,   0.1,
5571          1.0,    1.0,   0.1
5572     };
5573
5574     HRESULT hr;
5575     DWORD color;
5576     IDirect3DVertexShader9 *vertexshader = NULL;
5577     IDirect3DPixelShader9 *ps_1_shader = NULL;
5578     IDirect3DPixelShader9 *ps_2_shader = NULL;
5579     IDirect3DPixelShader9 *ps_3_shader = NULL;
5580     IDirect3DTexture9 *texture = NULL;
5581     D3DLOCKED_RECT lr;
5582     unsigned int x, y;
5583
5584     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5585
5586     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5587     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5588     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5589     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5590     for(y = 0; y < 512; y++) {
5591         for(x = 0; x < 512; x++) {
5592             double r_f = (double) x / (double) 512;
5593             double g_f = (double) y / (double) 512;
5594             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5595             unsigned short r = (unsigned short) (r_f * 65535.0);
5596             unsigned short g = (unsigned short) (g_f * 65535.0);
5597             dst[0] = r;
5598             dst[1] = g;
5599             dst[2] = 0;
5600             dst[3] = 65535;
5601         }
5602     }
5603     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5604     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5605
5606     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5607     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5608     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5609     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5610     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5611     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5612     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5613     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5614     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5615     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5616     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5617
5618     hr = IDirect3DDevice9_BeginScene(device);
5619     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5620     if(SUCCEEDED(hr))
5621     {
5622         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5623         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5624         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5625         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5626
5627         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5628         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5629         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5630         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5631
5632         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5633         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5635         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5636
5637         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5638         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5639         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5640         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5641         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5642         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5643         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5644         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5645         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5646         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5647
5648         hr = IDirect3DDevice9_EndScene(device);
5649         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5650     }
5651     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5652     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5653
5654     color = getPixelColor(device, 160, 120);
5655     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5656        (color & 0x0000ff00) == 0x0000ff00 &&
5657        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5658        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5659     color = getPixelColor(device, 160, 360);
5660     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5661        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5662        (color & 0x000000ff) == 0x00000000,
5663        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5664     color = getPixelColor(device, 480, 360);
5665     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5666        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5667        (color & 0x000000ff) == 0x00000000,
5668        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5669     color = getPixelColor(device, 480, 160);
5670     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5671        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5672        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5673        (color & 0x000000ff) == 0x00000000),
5674        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5675
5676     /* cleanup */
5677     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5678     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5679     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5680     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5681     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5682     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5683     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5684     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5685     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5686     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5687     if(texture) IDirect3DTexture9_Release(texture);
5688 }
5689
5690 void test_compare_instructions(IDirect3DDevice9 *device)
5691 {
5692     DWORD shader_sge_vec_code[] = {
5693         0xfffe0101,                                         /* vs_1_1                   */
5694         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5695         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5696         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5697         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5698         0x0000ffff                                          /* end                      */
5699     };
5700     DWORD shader_slt_vec_code[] = {
5701         0xfffe0101,                                         /* vs_1_1                   */
5702         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5703         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5704         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5705         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5706         0x0000ffff                                          /* end                      */
5707     };
5708     DWORD shader_sge_scalar_code[] = {
5709         0xfffe0101,                                         /* vs_1_1                   */
5710         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5711         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5712         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5713         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5714         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5715         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5716         0x0000ffff                                          /* end                      */
5717     };
5718     DWORD shader_slt_scalar_code[] = {
5719         0xfffe0101,                                         /* vs_1_1                   */
5720         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5721         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5722         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5723         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5724         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5725         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5726         0x0000ffff                                          /* end                      */
5727     };
5728     IDirect3DVertexShader9 *shader_sge_vec;
5729     IDirect3DVertexShader9 *shader_slt_vec;
5730     IDirect3DVertexShader9 *shader_sge_scalar;
5731     IDirect3DVertexShader9 *shader_slt_scalar;
5732     HRESULT hr, color;
5733     float quad1[] =  {
5734         -1.0,   -1.0,   0.1,
5735          0.0,   -1.0,   0.1,
5736         -1.0,    0.0,   0.1,
5737          0.0,    0.0,   0.1
5738     };
5739     float quad2[] =  {
5740          0.0,   -1.0,   0.1,
5741          1.0,   -1.0,   0.1,
5742          0.0,    0.0,   0.1,
5743          1.0,    0.0,   0.1
5744     };
5745     float quad3[] =  {
5746         -1.0,    0.0,   0.1,
5747          0.0,    0.0,   0.1,
5748         -1.0,    1.0,   0.1,
5749          0.0,    1.0,   0.1
5750     };
5751     float quad4[] =  {
5752          0.0,    0.0,   0.1,
5753          1.0,    0.0,   0.1,
5754          0.0,    1.0,   0.1,
5755          1.0,    1.0,   0.1
5756     };
5757     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5758     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5759
5760     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5761
5762     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5763     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5764     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5765     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5766     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5767     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5768     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5769     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5770     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5771     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5772     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5773     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5774     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5775     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5776
5777     hr = IDirect3DDevice9_BeginScene(device);
5778     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5779     if(SUCCEEDED(hr))
5780     {
5781         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5782         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5783         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5784         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5785
5786         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5787         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5788         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5789         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5790
5791         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5792         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5794         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5795
5796         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5797         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5798
5799         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5800         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5803
5804         hr = IDirect3DDevice9_EndScene(device);
5805         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5806     }
5807
5808     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5809     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5810
5811     color = getPixelColor(device, 160, 360);
5812     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5813     color = getPixelColor(device, 480, 360);
5814     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5815     color = getPixelColor(device, 160, 120);
5816     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5817     color = getPixelColor(device, 480, 160);
5818     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5819
5820     IDirect3DVertexShader9_Release(shader_sge_vec);
5821     IDirect3DVertexShader9_Release(shader_slt_vec);
5822     IDirect3DVertexShader9_Release(shader_sge_scalar);
5823     IDirect3DVertexShader9_Release(shader_slt_scalar);
5824 }
5825
5826 void test_vshader_input(IDirect3DDevice9 *device)
5827 {
5828     DWORD swapped_shader_code_3[] = {
5829         0xfffe0300,                                         /* vs_3_0               */
5830         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5831         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5832         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5833         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5834         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5835         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5836         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5837         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5838         0x0000ffff                                          /* end                  */
5839     };
5840     DWORD swapped_shader_code_1[] = {
5841         0xfffe0101,                                         /* vs_1_1               */
5842         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5843         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5844         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5845         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5846         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5847         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5848         0x0000ffff                                          /* end                  */
5849     };
5850     DWORD swapped_shader_code_2[] = {
5851         0xfffe0200,                                         /* vs_2_0               */
5852         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5853         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5854         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5855         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5856         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5857         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5858         0x0000ffff                                          /* end                  */
5859     };
5860     DWORD texcoord_color_shader_code_3[] = {
5861         0xfffe0300,                                         /* vs_3_0               */
5862         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5863         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5864         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5865         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5866         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5867         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5868         0x0000ffff                                          /* end                  */
5869     };
5870     DWORD texcoord_color_shader_code_2[] = {
5871         0xfffe0200,                                         /* vs_2_0               */
5872         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5873         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5874         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5875         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5876         0x0000ffff                                          /* end                  */
5877     };
5878     DWORD texcoord_color_shader_code_1[] = {
5879         0xfffe0101,                                         /* vs_1_1               */
5880         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5881         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5882         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5883         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5884         0x0000ffff                                          /* end                  */
5885     };
5886     DWORD color_color_shader_code_3[] = {
5887         0xfffe0300,                                         /* vs_3_0               */
5888         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5889         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5890         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5891         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5892         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5893         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5894         0x0000ffff                                          /* end                  */
5895     };
5896     DWORD color_color_shader_code_2[] = {
5897         0xfffe0200,                                         /* vs_2_0               */
5898         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5899         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5900         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5901         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5902         0x0000ffff                                          /* end                  */
5903     };
5904     DWORD color_color_shader_code_1[] = {
5905         0xfffe0101,                                         /* vs_1_1               */
5906         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5907         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5908         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5909         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5910         0x0000ffff                                          /* end                  */
5911     };
5912     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5913     HRESULT hr;
5914     DWORD color, r, g, b;
5915     float quad1[] =  {
5916         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5917          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5918         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5919          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5920     };
5921     float quad2[] =  {
5922          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5923          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5924          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5925          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5926     };
5927     float quad3[] =  {
5928         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5929          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5930         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5931          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5932     };
5933     float quad4[] =  {
5934          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5935          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5936          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5937          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5938     };
5939     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5940         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5941         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5942         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5943         D3DDECL_END()
5944     };
5945     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5946         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5947         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5948         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5949         D3DDECL_END()
5950     };
5951     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5952         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5953         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5954         D3DDECL_END()
5955     };
5956     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5957         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5958         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5959         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5960         D3DDECL_END()
5961     };
5962     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5963         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5964         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5965         D3DDECL_END()
5966     };
5967     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5968         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5969         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5970         D3DDECL_END()
5971     };
5972     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5973         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5974         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5975         D3DDECL_END()
5976     };
5977     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5978         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5979         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5980         D3DDECL_END()
5981     };
5982     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5983     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5984     unsigned int i;
5985     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5986     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5987
5988     struct vertex quad1_color[] =  {
5989        {-1.0,   -1.0,   0.1,    0x00ff8040},
5990        { 0.0,   -1.0,   0.1,    0x00ff8040},
5991        {-1.0,    0.0,   0.1,    0x00ff8040},
5992        { 0.0,    0.0,   0.1,    0x00ff8040}
5993     };
5994     struct vertex quad2_color[] =  {
5995        { 0.0,   -1.0,   0.1,    0x00ff8040},
5996        { 1.0,   -1.0,   0.1,    0x00ff8040},
5997        { 0.0,    0.0,   0.1,    0x00ff8040},
5998        { 1.0,    0.0,   0.1,    0x00ff8040}
5999     };
6000     struct vertex quad3_color[] =  {
6001        {-1.0,    0.0,   0.1,    0x00ff8040},
6002        { 0.0,    0.0,   0.1,    0x00ff8040},
6003        {-1.0,    1.0,   0.1,    0x00ff8040},
6004        { 0.0,    1.0,   0.1,    0x00ff8040}
6005     };
6006     float quad4_color[] =  {
6007          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6008          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6009          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6010          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6011     };
6012
6013     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6014     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6015     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6016     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6017     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6018     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6019     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6020     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6021
6022     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6023     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6024     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6025     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6026     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6027     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6028     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6029     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6030
6031     for(i = 1; i <= 3; i++) {
6032         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6033         if(i == 3) {
6034             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6035             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6036         } else if(i == 2){
6037             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6038             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6039         } else if(i == 1) {
6040             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6041             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6042         }
6043
6044         hr = IDirect3DDevice9_BeginScene(device);
6045         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6046         if(SUCCEEDED(hr))
6047         {
6048             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6049             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6050
6051             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6052             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6053             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6054             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6055
6056             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6057             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6058             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6059             if(i == 3 || i == 2) {
6060                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6061             } else if(i == 1) {
6062                 /* Succeeds or fails, depending on SW or HW vertex processing */
6063                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6064             }
6065
6066             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6067             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6068             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6069             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6070
6071             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6072             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6073             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6074             if(i == 3 || i == 2) {
6075                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6076             } else if(i == 1) {
6077                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6078             }
6079
6080             hr = IDirect3DDevice9_EndScene(device);
6081             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6082         }
6083
6084         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6085         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6086
6087         if(i == 3 || i == 2) {
6088             color = getPixelColor(device, 160, 360);
6089             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6090                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6091
6092             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6093             color = getPixelColor(device, 480, 360);
6094             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6095                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6096             color = getPixelColor(device, 160, 120);
6097             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6098             ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
6099                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6100
6101             color = getPixelColor(device, 480, 160);
6102             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6103         } else if(i == 1) {
6104             color = getPixelColor(device, 160, 360);
6105             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6106                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6107             color = getPixelColor(device, 480, 360);
6108             /* Accept the clear color as well in this case, since SW VP returns an error */
6109             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6110             color = getPixelColor(device, 160, 120);
6111             ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6112                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6113             color = getPixelColor(device, 480, 160);
6114             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6115         }
6116
6117         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6118         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6119
6120         /* Now find out if the whole streams are re-read, or just the last active value for the
6121          * vertices is used.
6122          */
6123         hr = IDirect3DDevice9_BeginScene(device);
6124         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6125         if(SUCCEEDED(hr))
6126         {
6127             float quad1_modified[] =  {
6128                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6129                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6130                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6131                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6132             };
6133             float quad2_modified[] =  {
6134                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6135                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6136                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6137                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6138             };
6139
6140             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6141             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6142
6143             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6144             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6145             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6146             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6147
6148             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6149             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6150             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6151             if(i == 3 || i == 2) {
6152                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6153             } else if(i == 1) {
6154                 /* Succeeds or fails, depending on SW or HW vertex processing */
6155                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6156             }
6157
6158             hr = IDirect3DDevice9_EndScene(device);
6159             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6160         }
6161         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6162         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6163
6164         color = getPixelColor(device, 480, 350);
6165         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6166          * as well.
6167          *
6168          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6169          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6170          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6171          * refrast's result.
6172          *
6173          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6174          */
6175         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6176            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6177         color = getPixelColor(device, 160, 120);
6178
6179         IDirect3DDevice9_SetVertexShader(device, NULL);
6180         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6181
6182         IDirect3DVertexShader9_Release(swapped_shader);
6183     }
6184
6185     for(i = 1; i <= 3; i++) {
6186         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6187         if(i == 3) {
6188             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6189             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6190             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6191             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6192         } else if(i == 2){
6193             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6194             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6195             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6196             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6197         } else if(i == 1) {
6198             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6199             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6200             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6201             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6202         }
6203
6204         hr = IDirect3DDevice9_BeginScene(device);
6205         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6206         if(SUCCEEDED(hr))
6207         {
6208             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6209             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6210             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6212             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6213             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6214
6215             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6216             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6217
6218             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6219             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6220             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6221             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6222             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6223             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6224
6225             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6226             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6227             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6228             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6229             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6230             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6231
6232             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6233             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6234             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6235             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6236
6237             hr = IDirect3DDevice9_EndScene(device);
6238             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6239         }
6240         IDirect3DDevice9_SetVertexShader(device, NULL);
6241         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6242
6243         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6244         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6245
6246         color = getPixelColor(device, 160, 360);
6247         r = (color & 0x00ff0000) >> 16;
6248         g = (color & 0x0000ff00) >>  8;
6249         b = (color & 0x000000ff) >>  0;
6250         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6251            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6252         color = getPixelColor(device, 480, 360);
6253         r = (color & 0x00ff0000) >> 16;
6254         g = (color & 0x0000ff00) >>  8;
6255         b = (color & 0x000000ff) >>  0;
6256         ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6257            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6258         color = getPixelColor(device, 160, 120);
6259         r = (color & 0x00ff0000) >> 16;
6260         g = (color & 0x0000ff00) >>  8;
6261         b = (color & 0x000000ff) >>  0;
6262         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6263            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6264         color = getPixelColor(device, 480, 160);
6265         r = (color & 0x00ff0000) >> 16;
6266         g = (color & 0x0000ff00) >>  8;
6267         b = (color & 0x000000ff) >>  0;
6268         ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6269            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6270
6271         IDirect3DVertexShader9_Release(texcoord_color_shader);
6272         IDirect3DVertexShader9_Release(color_color_shader);
6273     }
6274
6275     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6276     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6277     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6278     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6279
6280     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6281     IDirect3DVertexDeclaration9_Release(decl_color_color);
6282     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6283     IDirect3DVertexDeclaration9_Release(decl_color_float);
6284 }
6285
6286 static void srgbtexture_test(IDirect3DDevice9 *device)
6287 {
6288     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6289      * texture stage state to render a quad using that texture.  The resulting
6290      * color components should be 0x36 (~ 0.21), per this formula:
6291      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6292      * This is true where srgb_color > 0.04045.
6293      */
6294     IDirect3D9 *d3d = NULL;
6295     HRESULT hr;
6296     LPDIRECT3DTEXTURE9 texture = NULL;
6297     LPDIRECT3DSURFACE9 surface = NULL;
6298     D3DLOCKED_RECT lr;
6299     DWORD color;
6300     float quad[] = {
6301         -1.0,       1.0,       0.0,     0.0,    0.0,
6302          1.0,       1.0,       0.0,     1.0,    0.0,
6303         -1.0,      -1.0,       0.0,     0.0,    1.0,
6304          1.0,      -1.0,       0.0,     1.0,    1.0,
6305     };
6306
6307
6308     memset(&lr, 0, sizeof(lr));
6309     IDirect3DDevice9_GetDirect3D(device, &d3d);
6310     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6311                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6312                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6313         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6314         goto out;
6315     }
6316
6317     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6318                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6319                                         &texture, NULL);
6320     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6321     if(!texture) {
6322         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6323         goto out;
6324     }
6325     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6326     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6327
6328     fill_surface(surface, 0xff7f7f7f);
6329     IDirect3DSurface9_Release(surface);
6330
6331     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6332     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6333     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6334     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6335
6336     hr = IDirect3DDevice9_BeginScene(device);
6337     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6338     if(SUCCEEDED(hr))
6339     {
6340         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6341         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6342
6343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6345
6346
6347         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6348         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6349
6350         hr = IDirect3DDevice9_EndScene(device);
6351         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6352     }
6353
6354     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6355     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6356     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6357     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6358
6359     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6360     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6361
6362     color = getPixelColor(device, 320, 240);
6363     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6364
6365 out:
6366     if(texture) IDirect3DTexture9_Release(texture);
6367     IDirect3D9_Release(d3d);
6368 }
6369
6370 static void shademode_test(IDirect3DDevice9 *device)
6371 {
6372     /* Render a quad and try all of the different fixed function shading models. */
6373     HRESULT hr;
6374     DWORD color0, color1;
6375     DWORD color0_gouraud = 0, color1_gouraud = 0;
6376     BYTE r, g, b;
6377     DWORD shademode = D3DSHADE_FLAT;
6378     DWORD primtype = D3DPT_TRIANGLESTRIP;
6379     LPVOID data = NULL;
6380     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6381     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6382     UINT i, j;
6383     struct vertex quad_strip[] =
6384     {
6385         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6386         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6387         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6388         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6389     };
6390     struct vertex quad_list[] =
6391     {
6392         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6393         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6394         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6395
6396         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6397         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6398         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6399     };
6400
6401     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6402                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6403     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6404     if (FAILED(hr)) goto bail;
6405
6406     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6407                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6408     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6409     if (FAILED(hr)) goto bail;
6410
6411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6413
6414     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6415     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6416
6417     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6418     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6419     memcpy(data, quad_strip, sizeof(quad_strip));
6420     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6421     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6422
6423     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6424     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6425     memcpy(data, quad_list, sizeof(quad_list));
6426     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6427     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6428
6429     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6430      * the color fixups we have to do for FLAT shading will be dependent on that. */
6431     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6432     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6433
6434     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6435     for (j=0; j<2; j++) {
6436
6437         /* Inner loop just changes the D3DRS_SHADEMODE */
6438         for (i=0; i<3; i++) {
6439             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6440             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6441
6442             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6443             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6444
6445             hr = IDirect3DDevice9_BeginScene(device);
6446             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6447             if(SUCCEEDED(hr))
6448             {
6449                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6450                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6451
6452                 hr = IDirect3DDevice9_EndScene(device);
6453                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6454             }
6455
6456             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6457             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6458
6459             /* Sample two spots from the output */
6460             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6461             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6462             switch(shademode) {
6463                 case D3DSHADE_FLAT:
6464                     /* Should take the color of the first vertex of each triangle */
6465                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6466                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6467                     shademode = D3DSHADE_GOURAUD;
6468                     break;
6469                 case D3DSHADE_GOURAUD:
6470                     /* Should be an interpolated blend */
6471
6472                     r = (color0 & 0x00ff0000) >> 16;
6473                     g = (color0 & 0x0000ff00) >>  8;
6474                     b = (color0 & 0x000000ff);
6475                     ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6476                        "GOURAUD shading has color0 %08x, expected 0x000dca28\n", color0);
6477                     r = (color1 & 0x00ff0000) >> 16;
6478                     g = (color1 & 0x0000ff00) >>  8;
6479                     b = (color1 & 0x000000ff);
6480                     ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6481                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6482
6483                     color0_gouraud = color0;
6484                     color1_gouraud = color1;
6485
6486                     shademode = D3DSHADE_PHONG;
6487                     break;
6488                 case D3DSHADE_PHONG:
6489                     /* Should be the same as GOURAUD, since no hardware implements this */
6490                     r = (color0 & 0x00ff0000) >> 16;
6491                     g = (color0 & 0x0000ff00) >>  8;
6492                     b = (color0 & 0x000000ff);
6493                     ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6494                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6495                     r = (color1 & 0x00ff0000) >> 16;
6496                     g = (color1 & 0x0000ff00) >>  8;
6497                     b = (color1 & 0x000000ff);
6498                     ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6499                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6500
6501                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6502                             color0_gouraud, color0);
6503                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6504                             color1_gouraud, color1);
6505                     break;
6506             }
6507         }
6508         /* Now, do it all over again with a TRIANGLELIST */
6509         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6510         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6511         primtype = D3DPT_TRIANGLELIST;
6512         shademode = D3DSHADE_FLAT;
6513     }
6514
6515 bail:
6516     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6517     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6518     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6519     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6520
6521     if (vb_strip)
6522         IDirect3DVertexBuffer9_Release(vb_strip);
6523     if (vb_list)
6524         IDirect3DVertexBuffer9_Release(vb_list);
6525 }
6526
6527
6528 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6529 {
6530     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6531      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6532      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6533      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6534      * 0.73
6535      *
6536      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6537      * so use shaders for this task
6538      */
6539     IDirect3DPixelShader9 *pshader;
6540     IDirect3DVertexShader9 *vshader;
6541     IDirect3D9 *d3d;
6542     DWORD vshader_code[] = {
6543         0xfffe0101,                                                             /* vs_1_1                       */
6544         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6545         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6546         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6547         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6548         0x0000ffff                                                              /* end                          */
6549     };
6550     DWORD pshader_code[] = {
6551         0xffff0101,                                                             /* ps_1_1                       */
6552         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6553         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6554         0x0000ffff                                                              /* end                          */
6555     };
6556     const float quad[] = {
6557        -1.0,   -1.0,    0.1,
6558         1.0,   -1.0,    0.1,
6559        -1.0,    1.0,    0.1,
6560         1.0,    1.0,    0.1
6561     };
6562     HRESULT hr;
6563     DWORD color;
6564
6565     IDirect3DDevice9_GetDirect3D(device, &d3d);
6566     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6567      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6568      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6569      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6570      * works
6571      */
6572     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6573                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6574                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6575         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6576         IDirect3D9_Release(d3d);
6577         return;
6578     }
6579     IDirect3D9_Release(d3d);
6580
6581     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6582     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6583
6584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6585     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6586     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6587     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6588     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6589     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6590     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6591     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6592     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6593     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6594
6595     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6596     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6597     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6598     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6599     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6600     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6601     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6602     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6603     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6604     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6605
6606     hr = IDirect3DDevice9_BeginScene(device);
6607     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6608     if(SUCCEEDED(hr)) {
6609         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6610         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6611
6612         hr = IDirect3DDevice9_EndScene(device);
6613         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6614     }
6615
6616     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6617     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6618     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6619     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6620     IDirect3DPixelShader9_Release(pshader);
6621     IDirect3DVertexShader9_Release(vshader);
6622
6623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6624     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6627
6628     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6629     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6630     color = getPixelColor(device, 160, 360);
6631     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6632        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6633 }
6634
6635 static void alpha_test(IDirect3DDevice9 *device)
6636 {
6637     HRESULT hr;
6638     IDirect3DTexture9 *offscreenTexture;
6639     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6640     DWORD color, red, green, blue;
6641
6642     struct vertex quad1[] =
6643     {
6644         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6645         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6646         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6647         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6648     };
6649     struct vertex quad2[] =
6650     {
6651         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6652         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6653         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6654         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6655     };
6656     static const float composite_quad[][5] = {
6657         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6658         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6659         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6660         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6661     };
6662
6663     /* Clear the render target with alpha = 0.5 */
6664     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6665     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6666
6667     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6668     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6669
6670     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6671     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6672     if(!backbuffer) {
6673         goto out;
6674     }
6675
6676     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6677     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6678     if(!offscreen) {
6679         goto out;
6680     }
6681
6682     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6683     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6684
6685     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6686     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6687     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6688     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6689     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6690     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6691     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6692     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6693     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6694     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6695
6696     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6697     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6698     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6699
6700         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
6701          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
6702          * the input alpha
6703          *
6704          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
6705          * They give essentially ZERO and ONE blend factors
6706          */
6707         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6708         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6709         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6710         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6711         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6712         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6713
6714         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6715         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6716         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6717         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6719         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6720
6721         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
6722          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
6723          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
6724          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
6725          * vertices
6726          */
6727         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6728         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6729         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6730         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6731
6732         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6733         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6734         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6735         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6736         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6737         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6738
6739         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6740         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6741         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6742         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6744         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6745
6746         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6747         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6748
6749         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6750          * Disable alpha blending for the final composition
6751          */
6752         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6753         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6754         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6755         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6756
6757         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6758         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6759         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6760         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6761         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6762         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6763
6764         hr = IDirect3DDevice9_EndScene(device);
6765         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6766     }
6767
6768     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6769
6770     color = getPixelColor(device, 160, 360);
6771     red =   (color & 0x00ff0000) >> 16;
6772     green = (color & 0x0000ff00) >>  8;
6773     blue =  (color & 0x000000ff);
6774     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6775        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6776
6777     color = getPixelColor(device, 160, 120);
6778     red =   (color & 0x00ff0000) >> 16;
6779     green = (color & 0x0000ff00) >>  8;
6780     blue =  (color & 0x000000ff);
6781     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6782        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6783
6784     color = getPixelColor(device, 480, 360);
6785     red =   (color & 0x00ff0000) >> 16;
6786     green = (color & 0x0000ff00) >>  8;
6787     blue =  (color & 0x000000ff);
6788     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6789        "SRCALPHA on texture returned color %08x, expected bar\n", color);
6790
6791     color = getPixelColor(device, 480, 120);
6792     red =   (color & 0x00ff0000) >> 16;
6793     green = (color & 0x0000ff00) >>  8;
6794     blue =  (color & 0x000000ff);
6795     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6796        "DSTALPHA on texture returned color %08x, expected 0x00800080\n", color);
6797
6798     out:
6799     /* restore things */
6800     if(backbuffer) {
6801         IDirect3DSurface9_Release(backbuffer);
6802     }
6803     if(offscreenTexture) {
6804         IDirect3DTexture9_Release(offscreenTexture);
6805     }
6806     if(offscreen) {
6807         IDirect3DSurface9_Release(offscreen);
6808     }
6809 }
6810
6811 struct vertex_shortcolor {
6812     float x, y, z;
6813     unsigned short r, g, b, a;
6814 };
6815 struct vertex_floatcolor {
6816     float x, y, z;
6817     float r, g, b, a;
6818 };
6819
6820 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6821 {
6822     HRESULT hr;
6823     BOOL s_ok, ub_ok, f_ok;
6824     DWORD color, size, i;
6825     void *data;
6826     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6827         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6828         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6829         D3DDECL_END()
6830     };
6831     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6832         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6833         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6834         D3DDECL_END()
6835     };
6836     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6837         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6838         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6839         D3DDECL_END()
6840     };
6841     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6842         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6843         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6844         D3DDECL_END()
6845     };
6846     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6847         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6848         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6849         D3DDECL_END()
6850     };
6851     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6852         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6853         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6854         D3DDECL_END()
6855     };
6856     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6857         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6858         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6859         D3DDECL_END()
6860     };
6861     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6862     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6863     IDirect3DVertexBuffer9 *vb, *vb2;
6864     struct vertex quad1[] =                             /* D3DCOLOR */
6865     {
6866         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6867         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6868         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6869         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6870     };
6871     struct vertex quad2[] =                             /* UBYTE4N */
6872     {
6873         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6874         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6875         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6876         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6877     };
6878     struct vertex_shortcolor quad3[] =                  /* short */
6879     {
6880         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6881         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6882         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6883         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6884     };
6885     struct vertex_floatcolor quad4[] =
6886     {
6887         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6888         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6889         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6890         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6891     };
6892     DWORD colors[] = {
6893         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6894         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6895         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6896         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6897         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6898         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6899         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6900         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6901         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6902         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6903         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6904         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6905         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6906         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6907         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6908         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6909     };
6910     float quads[] = {
6911         -1.0,   -1.0,     0.1,
6912         -1.0,    0.0,     0.1,
6913          0.0,   -1.0,     0.1,
6914          0.0,    0.0,     0.1,
6915
6916          0.0,   -1.0,     0.1,
6917          0.0,    0.0,     0.1,
6918          1.0,   -1.0,     0.1,
6919          1.0,    0.0,     0.1,
6920
6921          0.0,    0.0,     0.1,
6922          0.0,    1.0,     0.1,
6923          1.0,    0.0,     0.1,
6924          1.0,    1.0,     0.1,
6925
6926         -1.0,    0.0,     0.1,
6927         -1.0,    1.0,     0.1,
6928          0.0,    0.0,     0.1,
6929          0.0,    1.0,     0.1
6930     };
6931     struct tvertex quad_transformed[] = {
6932        {  90,    110,     0.1,      2.0,        0x00ffff00},
6933        { 570,    110,     0.1,      2.0,        0x00ffff00},
6934        {  90,    300,     0.1,      2.0,        0x00ffff00},
6935        { 570,    300,     0.1,      2.0,        0x00ffff00}
6936     };
6937     D3DCAPS9 caps;
6938
6939     memset(&caps, 0, sizeof(caps));
6940     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6941     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6942
6943     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6944     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6945
6946     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6947     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6948     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6949     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6950     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6951     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6952     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6953         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6954         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6955         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6956         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6957     } else {
6958         trace("D3DDTCAPS_UBYTE4N not supported\n");
6959         dcl_ubyte_2 = NULL;
6960         dcl_ubyte = NULL;
6961     }
6962     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6963     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6964     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6965     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6966
6967     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6968     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6969                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6970     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6971
6972     hr = IDirect3DDevice9_BeginScene(device);
6973     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6974     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6975     if(SUCCEEDED(hr)) {
6976         if(dcl_color) {
6977             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6978             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6979             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6980             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6981         }
6982
6983         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6984          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6985          * using software vertex processing. Doh!
6986          */
6987         if(dcl_ubyte) {
6988             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6989             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6990             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6991             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6992             ub_ok = SUCCEEDED(hr);
6993         }
6994
6995         if(dcl_short) {
6996             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6997             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6998             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6999             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7000             s_ok = SUCCEEDED(hr);
7001         }
7002
7003         if(dcl_float) {
7004             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7005             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7006             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7007             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7008             f_ok = SUCCEEDED(hr);
7009         }
7010
7011         hr = IDirect3DDevice9_EndScene(device);
7012         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7013     }
7014
7015     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7016     if(dcl_short) {
7017         color = getPixelColor(device, 480, 360);
7018         ok(color == 0x000000ff || !s_ok,
7019            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7020     }
7021     if(dcl_ubyte) {
7022         color = getPixelColor(device, 160, 120);
7023         ok(color == 0x0000ffff || !ub_ok,
7024            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7025     }
7026     if(dcl_color) {
7027         color = getPixelColor(device, 160, 360);
7028         ok(color == 0x00ffff00,
7029            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7030     }
7031     if(dcl_float) {
7032         color = getPixelColor(device, 480, 120);
7033         ok(color == 0x00ff0000 || !f_ok,
7034            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7035     }
7036
7037     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7038      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7039      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7040      * whether the immediate mode code works
7041      */
7042     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7043     hr = IDirect3DDevice9_BeginScene(device);
7044     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7045     if(SUCCEEDED(hr)) {
7046         if(dcl_color) {
7047             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7048             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7049             memcpy(data, quad1, sizeof(quad1));
7050             hr = IDirect3DVertexBuffer9_Unlock(vb);
7051             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7052             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7053             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7054             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7055             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7056             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7057             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7058         }
7059
7060         if(dcl_ubyte) {
7061             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7062             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7063             memcpy(data, quad2, sizeof(quad2));
7064             hr = IDirect3DVertexBuffer9_Unlock(vb);
7065             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7066             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7067             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7068             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7069             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7070             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7071             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7072                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7073             ub_ok = SUCCEEDED(hr);
7074         }
7075
7076         if(dcl_short) {
7077             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7078             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7079             memcpy(data, quad3, sizeof(quad3));
7080             hr = IDirect3DVertexBuffer9_Unlock(vb);
7081             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7082             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7083             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7084             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7085             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7086             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7087             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7088                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7089             s_ok = SUCCEEDED(hr);
7090         }
7091
7092         if(dcl_float) {
7093             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7094             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7095             memcpy(data, quad4, sizeof(quad4));
7096             hr = IDirect3DVertexBuffer9_Unlock(vb);
7097             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7098             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7099             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7100             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7101             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7102             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7103             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7104                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7105             f_ok = SUCCEEDED(hr);
7106         }
7107
7108         hr = IDirect3DDevice9_EndScene(device);
7109         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7110     }
7111
7112     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7113     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7114     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7115     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7116
7117     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7118     if(dcl_short) {
7119         color = getPixelColor(device, 480, 360);
7120         ok(color == 0x000000ff || !s_ok,
7121            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7122     }
7123     if(dcl_ubyte) {
7124         color = getPixelColor(device, 160, 120);
7125         ok(color == 0x0000ffff || !ub_ok,
7126            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7127     }
7128     if(dcl_color) {
7129         color = getPixelColor(device, 160, 360);
7130         ok(color == 0x00ffff00,
7131            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7132     }
7133     if(dcl_float) {
7134         color = getPixelColor(device, 480, 120);
7135         ok(color == 0x00ff0000 || !f_ok,
7136            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7137     }
7138
7139     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7140     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7141
7142     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7143     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7144     memcpy(data, quad_transformed, sizeof(quad_transformed));
7145     hr = IDirect3DVertexBuffer9_Unlock(vb);
7146     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7147
7148     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7149     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7150
7151     hr = IDirect3DDevice9_BeginScene(device);
7152     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7153     if(SUCCEEDED(hr)) {
7154         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7155         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7156         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7157         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7158
7159         hr = IDirect3DDevice9_EndScene(device);
7160         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7161     }
7162
7163     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7164     color = getPixelColor(device, 88, 108);
7165     ok(color == 0x000000ff,
7166        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7167     color = getPixelColor(device, 92, 108);
7168     ok(color == 0x000000ff,
7169        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7170     color = getPixelColor(device, 88, 112);
7171     ok(color == 0x000000ff,
7172        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7173     color = getPixelColor(device, 92, 112);
7174     ok(color == 0x00ffff00,
7175        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7176
7177     color = getPixelColor(device, 568, 108);
7178     ok(color == 0x000000ff,
7179        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7180     color = getPixelColor(device, 572, 108);
7181     ok(color == 0x000000ff,
7182        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7183     color = getPixelColor(device, 568, 112);
7184     ok(color == 0x00ffff00,
7185        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7186     color = getPixelColor(device, 572, 112);
7187     ok(color == 0x000000ff,
7188        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7189
7190     color = getPixelColor(device, 88, 298);
7191     ok(color == 0x000000ff,
7192        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7193     color = getPixelColor(device, 92, 298);
7194     ok(color == 0x00ffff00,
7195        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7196     color = getPixelColor(device, 88, 302);
7197     ok(color == 0x000000ff,
7198        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7199     color = getPixelColor(device, 92, 302);
7200     ok(color == 0x000000ff,
7201        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7202
7203     color = getPixelColor(device, 568, 298);
7204     ok(color == 0x00ffff00,
7205        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7206     color = getPixelColor(device, 572, 298);
7207     ok(color == 0x000000ff,
7208        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7209     color = getPixelColor(device, 568, 302);
7210     ok(color == 0x000000ff,
7211        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7212     color = getPixelColor(device, 572, 302);
7213     ok(color == 0x000000ff,
7214        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7215
7216     /* This test is pointless without those two declarations: */
7217     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7218         skip("color-ubyte switching test declarations aren't supported\n");
7219         goto out;
7220     }
7221
7222     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7223     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7224     memcpy(data, quads, sizeof(quads));
7225     hr = IDirect3DVertexBuffer9_Unlock(vb);
7226     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7227     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7228                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7229     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7230     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7231     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7232     memcpy(data, colors, sizeof(colors));
7233     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7234     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7235
7236     for(i = 0; i < 2; i++) {
7237         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7238         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7239
7240         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7241         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7242         if(i == 0) {
7243             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7244         } else {
7245             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7246         }
7247         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7248
7249         hr = IDirect3DDevice9_BeginScene(device);
7250         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7251         ub_ok = FALSE;
7252         if(SUCCEEDED(hr)) {
7253             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7254             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7255             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7256             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7257                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7258             ub_ok = SUCCEEDED(hr);
7259
7260             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7261             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7262             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7263             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7264
7265             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7266             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7267             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7268             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7269                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7270             ub_ok = (SUCCEEDED(hr) && ub_ok);
7271
7272             hr = IDirect3DDevice9_EndScene(device);
7273             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7274         }
7275
7276         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7277         if(i == 0) {
7278             color = getPixelColor(device, 480, 360);
7279             ok(color == 0x00ff0000,
7280                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7281             color = getPixelColor(device, 160, 120);
7282             ok(color == 0x00ffffff,
7283                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7284             color = getPixelColor(device, 160, 360);
7285             ok(color == 0x000000ff || !ub_ok,
7286                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7287             color = getPixelColor(device, 480, 120);
7288             ok(color == 0x000000ff || !ub_ok,
7289                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7290         } else {
7291             color = getPixelColor(device, 480, 360);
7292             ok(color == 0x000000ff,
7293                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7294             color = getPixelColor(device, 160, 120);
7295             ok(color == 0x00ffffff,
7296                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7297             color = getPixelColor(device, 160, 360);
7298             ok(color == 0x00ff0000 || !ub_ok,
7299                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7300             color = getPixelColor(device, 480, 120);
7301             ok(color == 0x00ff0000 || !ub_ok,
7302                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7303         }
7304     }
7305
7306     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7307     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7308     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7309     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7310     IDirect3DVertexBuffer9_Release(vb2);
7311
7312     out:
7313     IDirect3DVertexBuffer9_Release(vb);
7314     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7315     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7316     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7317     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7318     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7319     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7320     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7321 }
7322
7323 struct vertex_float16color {
7324     float x, y, z;
7325     DWORD c1, c2;
7326 };
7327
7328 static void test_vshader_float16(IDirect3DDevice9 *device)
7329 {
7330     HRESULT hr;
7331     DWORD color;
7332     void *data;
7333     static const D3DVERTEXELEMENT9 decl_elements[] = {
7334         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7335         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7336         D3DDECL_END()
7337     };
7338     IDirect3DVertexDeclaration9 *vdecl = NULL;
7339     IDirect3DVertexBuffer9 *buffer = NULL;
7340     IDirect3DVertexShader9 *shader;
7341     DWORD shader_code[] = {
7342         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7343         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7344         0x90e40001, 0x0000ffff
7345     };
7346     struct vertex_float16color quad[] = {
7347         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7348         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7349         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7350         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7351
7352         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7353         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7354         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7355         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7356
7357         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7358         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7359         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7360         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7361
7362         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7363         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7364         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7365         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7366     };
7367
7368     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7369     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7370
7371     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7372     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7373     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7374     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7375     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7376     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7377
7378     hr = IDirect3DDevice9_BeginScene(device);
7379     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7380     if(SUCCEEDED(hr)) {
7381         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7382         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7384         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7385         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7386         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7387         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7388         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7389         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7390         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7391
7392         hr = IDirect3DDevice9_EndScene(device);
7393         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7394     }
7395     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7396     color = getPixelColor(device, 480, 360);
7397     ok(color == 0x00ff0000,
7398        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7399     color = getPixelColor(device, 160, 120);
7400     ok(color == 0x00000000,
7401        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7402     color = getPixelColor(device, 160, 360);
7403     ok(color == 0x0000ff00,
7404        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7405     color = getPixelColor(device, 480, 120);
7406     ok(color == 0x000000ff,
7407        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7408
7409     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7410     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7411
7412     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7413                                              D3DPOOL_MANAGED, &buffer, NULL);
7414     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7415     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7416     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7417     memcpy(data, quad, sizeof(quad));
7418     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7419     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7420     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7421     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7422
7423     hr = IDirect3DDevice9_BeginScene(device);
7424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7425     if(SUCCEEDED(hr)) {
7426             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7427             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7428             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7429             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7430             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7431             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7432             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7433             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7434
7435             hr = IDirect3DDevice9_EndScene(device);
7436             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7437     }
7438
7439     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7440     color = getPixelColor(device, 480, 360);
7441     ok(color == 0x00ff0000,
7442        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7443     color = getPixelColor(device, 160, 120);
7444     ok(color == 0x00000000,
7445        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7446     color = getPixelColor(device, 160, 360);
7447     ok(color == 0x0000ff00,
7448        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7449     color = getPixelColor(device, 480, 120);
7450     ok(color == 0x000000ff,
7451        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7452
7453     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7454     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7455     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7456     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7457     IDirect3DDevice9_SetVertexShader(device, NULL);
7458     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7459
7460     IDirect3DVertexDeclaration9_Release(vdecl);
7461     IDirect3DVertexShader9_Release(shader);
7462     IDirect3DVertexBuffer9_Release(buffer);
7463 }
7464
7465 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7466 {
7467     D3DCAPS9 caps;
7468     IDirect3DTexture9 *texture;
7469     HRESULT hr;
7470     D3DLOCKED_RECT rect;
7471     unsigned int x, y;
7472     DWORD *dst, color;
7473     const float quad[] = {
7474         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7475          1.0,   -1.0,   0.1,    1.2,   -0.2,
7476         -1.0,    1.0,   0.1,   -0.2,    1.2,
7477          1.0,    1.0,   0.1,    1.2,    1.2
7478     };
7479     memset(&caps, 0, sizeof(caps));
7480
7481     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7482     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7483     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7484         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7485         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7486            "Card has conditional NP2 support without power of two restriction set\n");
7487         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7488         return;
7489     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7490         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7491         return;
7492     }
7493
7494     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7495     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7496
7497     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7498     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7499
7500     memset(&rect, 0, sizeof(rect));
7501     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7502     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7503     for(y = 0; y < 10; y++) {
7504         for(x = 0; x < 10; x++) {
7505             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7506             if(x == 0 || x == 9 || y == 0 || y == 9) {
7507                 *dst = 0x00ff0000;
7508             } else {
7509                 *dst = 0x000000ff;
7510             }
7511         }
7512     }
7513     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7514     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7515
7516     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7517     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7518     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7519     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7520     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7521     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7522     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7523     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7524
7525     hr = IDirect3DDevice9_BeginScene(device);
7526     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7527     if(SUCCEEDED(hr)) {
7528         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7529         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7530
7531         hr = IDirect3DDevice9_EndScene(device);
7532         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7533     }
7534
7535     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7536
7537     color = getPixelColor(device,    1,  1);
7538     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7539     color = getPixelColor(device, 639, 479);
7540     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7541
7542     color = getPixelColor(device, 135, 101);
7543     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7544     color = getPixelColor(device, 140, 101);
7545     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7546     color = getPixelColor(device, 135, 105);
7547     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7548     color = getPixelColor(device, 140, 105);
7549     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7550
7551     color = getPixelColor(device, 135, 376);
7552     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7553     color = getPixelColor(device, 140, 376);
7554     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7555     color = getPixelColor(device, 135, 379);
7556     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7557     color = getPixelColor(device, 140, 379);
7558     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7559
7560     color = getPixelColor(device, 500, 101);
7561     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7562     color = getPixelColor(device, 504, 101);
7563     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7564     color = getPixelColor(device, 500, 105);
7565     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7566     color = getPixelColor(device, 504, 105);
7567     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7568
7569     color = getPixelColor(device, 500, 376);
7570     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7571     color = getPixelColor(device, 504, 376);
7572     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7573     color = getPixelColor(device, 500, 380);
7574     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7575     color = getPixelColor(device, 504, 380);
7576     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7577
7578     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7579     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7580     IDirect3DTexture9_Release(texture);
7581 }
7582
7583 static void vFace_register_test(IDirect3DDevice9 *device)
7584 {
7585     HRESULT hr;
7586     DWORD color;
7587     const DWORD shader_code[] = {
7588         0xffff0300,                                                             /* ps_3_0                     */
7589         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7590         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7591         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7592         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7593         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7594         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7595         0x0000ffff                                                              /* END                        */
7596     };
7597     IDirect3DPixelShader9 *shader;
7598     IDirect3DTexture9 *texture;
7599     IDirect3DSurface9 *surface, *backbuffer;
7600     const float quad[] = {
7601         -1.0,   -1.0,   0.1,
7602          1.0,   -1.0,   0.1,
7603         -1.0,    0.0,   0.1,
7604
7605          1.0,   -1.0,   0.1,
7606          1.0,    0.0,   0.1,
7607         -1.0,    0.0,   0.1,
7608
7609         -1.0,    0.0,   0.1,
7610         -1.0,    1.0,   0.1,
7611          1.0,    0.0,   0.1,
7612
7613          1.0,    0.0,   0.1,
7614         -1.0,    1.0,   0.1,
7615          1.0,    1.0,   0.1,
7616     };
7617     const float blit[] = {
7618          0.0,   -1.0,   0.1,    0.0,    0.0,
7619          1.0,   -1.0,   0.1,    1.0,    0.0,
7620          0.0,    1.0,   0.1,    0.0,    1.0,
7621          1.0,    1.0,   0.1,    1.0,    1.0,
7622     };
7623
7624     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7625     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7626     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7627     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7628     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7629     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7630     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7631     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7632     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7633     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7634     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7635     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7636
7637     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7638     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7639
7640     hr = IDirect3DDevice9_BeginScene(device);
7641     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7642     if(SUCCEEDED(hr)) {
7643         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7644         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7645         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7646         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7647         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7648         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7649         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7650         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7651         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7652         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7653         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7654
7655         /* Blit the texture onto the back buffer to make it visible */
7656         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7657         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7658         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7659         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7660         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7661         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7662         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7663         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7664         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7665         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7666
7667         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7668         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7669
7670         hr = IDirect3DDevice9_EndScene(device);
7671         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7672     }
7673
7674     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7675     color = getPixelColor(device, 160, 360);
7676     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7677     color = getPixelColor(device, 160, 120);
7678     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7679     color = getPixelColor(device, 480, 360);
7680     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7681     color = getPixelColor(device, 480, 120);
7682     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7683
7684     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7685     IDirect3DDevice9_SetTexture(device, 0, NULL);
7686     IDirect3DPixelShader9_Release(shader);
7687     IDirect3DSurface9_Release(surface);
7688     IDirect3DSurface9_Release(backbuffer);
7689     IDirect3DTexture9_Release(texture);
7690 }
7691
7692 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7693 {
7694     HRESULT hr;
7695     DWORD color;
7696     int i;
7697     D3DCAPS9 caps;
7698
7699     static const float quad[][7] = {
7700         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7701         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7702         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7703         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7704     };
7705
7706     static const D3DVERTEXELEMENT9 decl_elements[] = {
7707         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7708         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7709         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7710         D3DDECL_END()
7711     };
7712
7713     /* use asymmetric matrix to test loading */
7714     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7715
7716     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7717     IDirect3DTexture9           *texture            = NULL;
7718
7719     memset(&caps, 0, sizeof(caps));
7720     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7721     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7722     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7723         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7724         return;
7725     } else {
7726         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7727          * They report that it is not supported, but after that bump mapping works properly. So just test
7728          * if the format is generally supported, and check the BUMPENVMAP flag
7729          */
7730         IDirect3D9 *d3d9;
7731
7732         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7733         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7734                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7735         IDirect3D9_Release(d3d9);
7736         if(FAILED(hr)) {
7737             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7738             return;
7739         }
7740     }
7741
7742     /* Generate the textures */
7743     generate_bumpmap_textures(device);
7744
7745     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7746     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7747     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7748     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7749     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7750     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7751     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7752     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7753
7754     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7755     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7756     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7757     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7758     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7759     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7760
7761     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7762     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7763     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7764     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7765     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7766     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7767
7768     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7769     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7770
7771     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7772     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7773
7774     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7775     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7776
7777
7778     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7779     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7780     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7781     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7782
7783     hr = IDirect3DDevice9_BeginScene(device);
7784     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7785
7786     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7787     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7788
7789     hr = IDirect3DDevice9_EndScene(device);
7790     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7791
7792     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7793     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7794
7795     color = getPixelColor(device, 320-32, 240);
7796     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7797     color = getPixelColor(device, 320+32, 240);
7798     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7799     color = getPixelColor(device, 320, 240-32);
7800     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7801     color = getPixelColor(device, 320, 240+32);
7802     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7803     color = getPixelColor(device, 320, 240);
7804     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7805     color = getPixelColor(device, 320+32, 240+32);
7806     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7807     color = getPixelColor(device, 320-32, 240+32);
7808     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7809     color = getPixelColor(device, 320+32, 240-32);
7810     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7811     color = getPixelColor(device, 320-32, 240-32);
7812     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7813
7814     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7815     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7816     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7817
7818     for(i = 0; i < 2; i++) {
7819         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7820         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7821         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7822         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7823         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7824         IDirect3DTexture9_Release(texture); /* To destroy it */
7825     }
7826
7827     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7828     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7829     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7830     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7831
7832 }
7833
7834 static void stencil_cull_test(IDirect3DDevice9 *device) {
7835     HRESULT hr;
7836     IDirect3DSurface9 *depthstencil = NULL;
7837     D3DSURFACE_DESC desc;
7838     float quad1[] = {
7839         -1.0,   -1.0,   0.1,
7840          0.0,   -1.0,   0.1,
7841         -1.0,    0.0,   0.1,
7842          0.0,    0.0,   0.1,
7843     };
7844     float quad2[] = {
7845          0.0,   -1.0,   0.1,
7846          1.0,   -1.0,   0.1,
7847          0.0,    0.0,   0.1,
7848          1.0,    0.0,   0.1,
7849     };
7850     float quad3[] = {
7851         0.0,    0.0,   0.1,
7852         1.0,    0.0,   0.1,
7853         0.0,    1.0,   0.1,
7854         1.0,    1.0,   0.1,
7855     };
7856     float quad4[] = {
7857         -1.0,    0.0,   0.1,
7858          0.0,    0.0,   0.1,
7859         -1.0,    1.0,   0.1,
7860          0.0,    1.0,   0.1,
7861     };
7862     struct vertex painter[] = {
7863        {-1.0,   -1.0,   0.0,    0x00000000},
7864        { 1.0,   -1.0,   0.0,    0x00000000},
7865        {-1.0,    1.0,   0.0,    0x00000000},
7866        { 1.0,    1.0,   0.0,    0x00000000},
7867     };
7868     WORD indices_cw[]  = {0, 1, 3};
7869     WORD indices_ccw[] = {0, 2, 3};
7870     unsigned int i;
7871     DWORD color;
7872
7873     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7874     if(depthstencil == NULL) {
7875         skip("No depth stencil buffer\n");
7876         return;
7877     }
7878     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7879     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7880     IDirect3DSurface9_Release(depthstencil);
7881     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7882         skip("No 4 or 8 bit stencil surface\n");
7883         return;
7884     }
7885
7886     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7887     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7888     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7889
7890     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7891     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7892     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7893     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7894     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7895     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7896     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7897     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7898
7899     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7900     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7901     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7902     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7903     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7904     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7905
7906     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7907     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7908     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7909     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7910
7911     /* First pass: Fill the stencil buffer with some values... */
7912     hr = IDirect3DDevice9_BeginScene(device);
7913     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7914     if(SUCCEEDED(hr))
7915     {
7916         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7917         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7918         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7919                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7920         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7921                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7922
7923         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7924         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7925         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7926         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7927         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7928                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7929         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7930                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7931
7932         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7933         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7934         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7935                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7936         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7937                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7938
7939         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7940         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7941         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7942                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7943         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7944                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7945
7946         hr = IDirect3DDevice9_EndScene(device);
7947         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7948     }
7949
7950     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7951     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7952     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7953     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7954     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7955     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7956     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7957     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7958     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7959     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7960     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7961     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7962     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7963
7964     /* 2nd pass: Make the stencil values visible */
7965     hr = IDirect3DDevice9_BeginScene(device);
7966     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7967     if(SUCCEEDED(hr))
7968     {
7969         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7970         for(i = 0; i < 16; i++) {
7971             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7972             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7973
7974             painter[0].diffuse = (i * 16); /* Creates shades of blue */
7975             painter[1].diffuse = (i * 16);
7976             painter[2].diffuse = (i * 16);
7977             painter[3].diffuse = (i * 16);
7978             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7979             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7980         }
7981         hr = IDirect3DDevice9_EndScene(device);
7982         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7983     }
7984
7985     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7986     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7987
7988     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7989     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7990
7991     color = getPixelColor(device, 160, 420);
7992     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7993     color = getPixelColor(device, 160, 300);
7994     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7995
7996     color = getPixelColor(device, 480, 420);
7997     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7998     color = getPixelColor(device, 480, 300);
7999     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8000
8001     color = getPixelColor(device, 160, 180);
8002     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8003     color = getPixelColor(device, 160, 60);
8004     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8005
8006     color = getPixelColor(device, 480, 180);
8007     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8008     color = getPixelColor(device, 480, 60);
8009     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8010 }
8011
8012 static void vpos_register_test(IDirect3DDevice9 *device)
8013 {
8014     HRESULT hr;
8015     DWORD color;
8016     const DWORD shader_code[] = {
8017     0xffff0300,                                                             /* ps_3_0                     */
8018     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8019     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8020     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8021     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8022     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8023     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8024     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8025     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8026     0x0000ffff                                                              /* end                        */
8027     };
8028     const DWORD shader_frac_code[] = {
8029     0xffff0300,                                                             /* ps_3_0                     */
8030     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8031     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8032     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8033     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8034     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8035     0x0000ffff                                                              /* end                        */
8036     };
8037     IDirect3DPixelShader9 *shader, *shader_frac;
8038     IDirect3DSurface9 *surface = NULL, *backbuffer;
8039     const float quad[] = {
8040         -1.0,   -1.0,   0.1,    0.0,    0.0,
8041          1.0,   -1.0,   0.1,    1.0,    0.0,
8042         -1.0,    1.0,   0.1,    0.0,    1.0,
8043          1.0,    1.0,   0.1,    1.0,    1.0,
8044     };
8045     D3DLOCKED_RECT lr;
8046     float constant[4] = {1.0, 0.0, 320, 240};
8047     DWORD *pos;
8048
8049     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8050     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8051     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8052     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8053     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8054     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8055     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8056     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8057     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8058     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8059     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8060     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8061
8062     hr = IDirect3DDevice9_BeginScene(device);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8064     if(SUCCEEDED(hr)) {
8065         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8066         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8067         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8068         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8069         hr = IDirect3DDevice9_EndScene(device);
8070         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8071     }
8072
8073     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8074     /* This has to be pixel exact */
8075     color = getPixelColor(device, 319, 239);
8076     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8077     color = getPixelColor(device, 320, 239);
8078     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8079     color = getPixelColor(device, 319, 240);
8080     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8081     color = getPixelColor(device, 320, 240);
8082     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8083
8084     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8085                                              &surface, NULL);
8086     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8087     hr = IDirect3DDevice9_BeginScene(device);
8088     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8089     if(SUCCEEDED(hr)) {
8090         constant[2] = 16; constant[3] = 16;
8091         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8092         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8093         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8094         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8096         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8097         hr = IDirect3DDevice9_EndScene(device);
8098         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8099     }
8100     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8101     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8102
8103     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8104     color = *pos & 0x00ffffff;
8105     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8106     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8107     color = *pos & 0x00ffffff;
8108     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8109     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8110     color = *pos & 0x00ffffff;
8111     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8112     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8113     color = *pos & 0x00ffffff;
8114     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8115
8116     hr = IDirect3DSurface9_UnlockRect(surface);
8117     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8118
8119     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8120      * have full control over the multisampling setting inside this test
8121      */
8122     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8123     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8124     hr = IDirect3DDevice9_BeginScene(device);
8125     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8126     if(SUCCEEDED(hr)) {
8127         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8128         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8129         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8130         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8131         hr = IDirect3DDevice9_EndScene(device);
8132         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8133     }
8134     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8135     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8136
8137     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8138     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8139
8140     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8141     color = *pos & 0x00ffffff;
8142     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8143
8144     hr = IDirect3DSurface9_UnlockRect(surface);
8145     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8146
8147     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8148     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8149     IDirect3DPixelShader9_Release(shader);
8150     IDirect3DPixelShader9_Release(shader_frac);
8151     if(surface) IDirect3DSurface9_Release(surface);
8152     IDirect3DSurface9_Release(backbuffer);
8153 }
8154
8155 static void pointsize_test(IDirect3DDevice9 *device)
8156 {
8157     HRESULT hr;
8158     D3DCAPS9 caps;
8159     D3DMATRIX matrix;
8160     D3DMATRIX identity;
8161     float ptsize, ptsize_orig;
8162     DWORD color;
8163
8164     const float vertices[] = {
8165         64,     64,     0.1,
8166         128,    64,     0.1,
8167         192,    64,     0.1,
8168         256,    64,     0.1,
8169         320,    64,     0.1,
8170         384,    64,     0.1
8171     };
8172
8173     /* 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 */
8174     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;
8175     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;
8176     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;
8177     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;
8178
8179     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;
8180     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;
8181     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;
8182     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;
8183
8184     memset(&caps, 0, sizeof(caps));
8185     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8186     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8187     if(caps.MaxPointSize < 32.0) {
8188         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8189         return;
8190     }
8191
8192     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8193     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8194     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8195     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8196     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8197     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8198     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8199     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8200
8201     hr = IDirect3DDevice9_BeginScene(device);
8202     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8203     if(SUCCEEDED(hr)) {
8204         ptsize = 16.0;
8205         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8206         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8207         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8208         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8209
8210         ptsize = 32.0;
8211         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8212         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8213         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8214         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8215
8216         ptsize = 31.5;
8217         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8218         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8219         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8220         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8221
8222         if(caps.MaxPointSize >= 64.0) {
8223             ptsize = 64.0;
8224             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8225             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8226             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8227             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8228
8229             ptsize = 63.75;
8230             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8231             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8232             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8233             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8234         }
8235
8236         ptsize = 1.0;
8237         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8238         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8239         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8240         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8241
8242         hr = IDirect3DDevice9_EndScene(device);
8243         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8244     }
8245     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8246     color = getPixelColor(device, 64-9, 64-9);
8247     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8248     color = getPixelColor(device, 64-8, 64-8);
8249     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8250     color = getPixelColor(device, 64-7, 64-7);
8251     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8252     color = getPixelColor(device, 64+7, 64+7);
8253     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8254     color = getPixelColor(device, 64+8, 64+8);
8255     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8256     color = getPixelColor(device, 64+9, 64+9);
8257     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8258
8259     color = getPixelColor(device, 128-17, 64-17);
8260     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8261     color = getPixelColor(device, 128-16, 64-16);
8262     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8263     color = getPixelColor(device, 128-15, 64-15);
8264     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8265     color = getPixelColor(device, 128+15, 64+15);
8266     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8267     color = getPixelColor(device, 128+16, 64+16);
8268     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8269     color = getPixelColor(device, 128+17, 64+17);
8270     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8271
8272     color = getPixelColor(device, 192-17, 64-17);
8273     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8274     color = getPixelColor(device, 192-16, 64-16);
8275     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8276     color = getPixelColor(device, 192-15, 64-15);
8277     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8278     color = getPixelColor(device, 192+15, 64+15);
8279     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8280     color = getPixelColor(device, 192+16, 64+16);
8281     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8282     color = getPixelColor(device, 192+17, 64+17);
8283     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8284
8285     if(caps.MaxPointSize >= 64.0) {
8286         color = getPixelColor(device, 256-33, 64-33);
8287         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8288         color = getPixelColor(device, 256-32, 64-32);
8289         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8290         color = getPixelColor(device, 256-31, 64-31);
8291         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8292         color = getPixelColor(device, 256+31, 64+31);
8293         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8294         color = getPixelColor(device, 256+32, 64+32);
8295         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8296         color = getPixelColor(device, 256+33, 64+33);
8297         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8298
8299         color = getPixelColor(device, 384-33, 64-33);
8300         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8301         color = getPixelColor(device, 384-32, 64-32);
8302         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8303         color = getPixelColor(device, 384-31, 64-31);
8304         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8305         color = getPixelColor(device, 384+31, 64+31);
8306         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8307         color = getPixelColor(device, 384+32, 64+32);
8308         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8309         color = getPixelColor(device, 384+33, 64+33);
8310         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8311     }
8312
8313     color = getPixelColor(device, 320-1, 64-1);
8314     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8315     color = getPixelColor(device, 320-0, 64-0);
8316     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8317     color = getPixelColor(device, 320+1, 64+1);
8318     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8319
8320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8322     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8323     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8324 }
8325
8326 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8327 {
8328     HRESULT hr;
8329     IDirect3DPixelShader9 *ps;
8330     IDirect3DTexture9 *tex1, *tex2;
8331     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8332     D3DCAPS9 caps;
8333     DWORD color;
8334     DWORD shader_code[] = {
8335     0xffff0300,                                                             /* ps_3_0             */
8336     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8337     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8338     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8339     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8340     0x0000ffff                                                              /* END                */
8341     };
8342     float quad[] = {
8343        -1.0,   -1.0,    0.1,
8344         1.0,   -1.0,    0.1,
8345        -1.0,    1.0,    0.1,
8346         1.0,    1.0,    0.1,
8347     };
8348     float texquad[] = {
8349        -1.0,   -1.0,    0.1,    0.0,    0.0,
8350         0.0,   -1.0,    0.1,    1.0,    0.0,
8351        -1.0,    1.0,    0.1,    0.0,    1.0,
8352         0.0,    1.0,    0.1,    1.0,    1.0,
8353
8354         0.0,   -1.0,    0.1,    0.0,    0.0,
8355         1.0,   -1.0,    0.1,    1.0,    0.0,
8356         0.0,    1.0,    0.1,    0.0,    1.0,
8357         1.0,    1.0,    0.1,    1.0,    1.0,
8358     };
8359
8360     memset(&caps, 0, sizeof(caps));
8361     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8362     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8363     if(caps.NumSimultaneousRTs < 2) {
8364         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8365         return;
8366     }
8367
8368     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8369     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8370
8371     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8372     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8373     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8374     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8375     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8376     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8377
8378     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8379     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8380     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8381     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8382     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8383     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8384
8385     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8386     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8387     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8388     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8389     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8390     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8391     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8392     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8393
8394     hr = IDirect3DDevice9_BeginScene(device);
8395     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8396     if(SUCCEEDED(hr)) {
8397         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8398         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8399
8400         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8401         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8402         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8403         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8404         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8405         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8406         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8407         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8408
8409         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8410         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8411         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8412         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8413
8414         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8415         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8416         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8417         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8418
8419         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8420         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8421
8422         hr = IDirect3DDevice9_EndScene(device);
8423         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8424     }
8425
8426     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8427     color = getPixelColor(device, 160, 240);
8428     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8429     color = getPixelColor(device, 480, 240);
8430     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8431
8432     IDirect3DPixelShader9_Release(ps);
8433     IDirect3DTexture9_Release(tex1);
8434     IDirect3DTexture9_Release(tex2);
8435     IDirect3DSurface9_Release(surf1);
8436     IDirect3DSurface9_Release(surf2);
8437     IDirect3DSurface9_Release(backbuf);
8438 }
8439
8440 struct formats {
8441     const char *fmtName;
8442     D3DFORMAT textureFormat;
8443     DWORD resultColorBlending;
8444     DWORD resultColorNoBlending;
8445 };
8446
8447 const struct formats test_formats[] = {
8448   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8449   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8450   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8451   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8452   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8453   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8454   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8455   { NULL, 0 }
8456 };
8457
8458 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8459 {
8460     HRESULT hr;
8461     IDirect3DTexture9 *offscreenTexture = NULL;
8462     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8463     IDirect3D9 *d3d = NULL;
8464     DWORD color;
8465     DWORD r0, g0, b0, r1, g1, b1;
8466     int fmt_index;
8467
8468     static const float quad[][5] = {
8469         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8470         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8471         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8472         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8473     };
8474
8475     /* Quad with R=0x10, G=0x20 */
8476     static const struct vertex quad1[] = {
8477         {-1.0f, -1.0f, 0.1f, 0x80102000},
8478         {-1.0f,  1.0f, 0.1f, 0x80102000},
8479         { 1.0f, -1.0f, 0.1f, 0x80102000},
8480         { 1.0f,  1.0f, 0.1f, 0x80102000},
8481     };
8482
8483     /* Quad with R=0x20, G=0x10 */
8484     static const struct vertex quad2[] = {
8485         {-1.0f, -1.0f, 0.1f, 0x80201000},
8486         {-1.0f,  1.0f, 0.1f, 0x80201000},
8487         { 1.0f, -1.0f, 0.1f, 0x80201000},
8488         { 1.0f,  1.0f, 0.1f, 0x80201000},
8489     };
8490
8491     IDirect3DDevice9_GetDirect3D(device, &d3d);
8492
8493     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8494     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8495     if(!backbuffer) {
8496         goto out;
8497     }
8498
8499     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8500     {
8501         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8502         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8503            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8504            continue;
8505         }
8506
8507         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8508         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8509
8510         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8511         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8512         if(!offscreenTexture) {
8513             continue;
8514         }
8515
8516         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8517         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8518         if(!offscreen) {
8519             continue;
8520         }
8521
8522         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8523         ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8524
8525         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8526         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8527         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8528         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8529         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8530         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8531         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8532         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8533         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8534         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8535
8536         /* Below we will draw two quads with different colors and try to blend them together.
8537          * The result color is compared with the expected outcome.
8538          */
8539         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8540             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8541             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8542             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8543             ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8544
8545             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8546             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8547
8548             /* Draw a quad using color 0x0010200 */
8549             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8550             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8551             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8552             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8553             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8554             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8555
8556             /* Draw a quad using color 0x0020100 */
8557             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8558             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8559             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8560             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8561             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8562             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8563
8564             /* We don't want to blend the result on the backbuffer */
8565             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8566             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8567
8568             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8569             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8570             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8571             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8572             ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8573
8574             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8575             ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8576
8577             /* This time with the texture */
8578             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8579             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8580
8581             IDirect3DDevice9_EndScene(device);
8582         }
8583         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8584
8585
8586         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8587             /* Compare the color of the center quad with our expectation */
8588             color = getPixelColor(device, 320, 240);
8589             r0 = (color & 0x00ff0000) >> 16;
8590             g0 = (color & 0x0000ff00) >>  8;
8591             b0 = (color & 0x000000ff) >>  0;
8592
8593             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8594             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8595             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8596
8597             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8598                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8599                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8600                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8601         } else {
8602             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8603              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8604              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8605             color = getPixelColor(device, 320, 240);
8606             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);
8607         }
8608
8609         IDirect3DDevice9_SetTexture(device, 0, NULL);
8610         if(offscreenTexture) {
8611             IDirect3DTexture9_Release(offscreenTexture);
8612         }
8613         if(offscreen) {
8614             IDirect3DSurface9_Release(offscreen);
8615         }
8616     }
8617
8618 out:
8619     /* restore things */
8620     if(backbuffer) {
8621         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8622         IDirect3DSurface9_Release(backbuffer);
8623     }
8624 }
8625
8626 static void tssargtemp_test(IDirect3DDevice9 *device)
8627 {
8628     HRESULT hr;
8629     DWORD color;
8630     static const struct vertex quad[] = {
8631         {-1.0,     -1.0,    0.1,    0x00ff0000},
8632         { 1.0,     -1.0,    0.1,    0x00ff0000},
8633         {-1.0,      1.0,    0.1,    0x00ff0000},
8634         { 1.0,      1.0,    0.1,    0x00ff0000}
8635     };
8636     D3DCAPS9 caps;
8637
8638     memset(&caps, 0, sizeof(caps));
8639     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8640     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8641     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8642         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8643         return;
8644     }
8645
8646     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8648
8649     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8650     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8651     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8652     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8653
8654     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8655     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8656     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8657     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8658     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8659     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8660
8661     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8662     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8663     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8664     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8665     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8666     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8667
8668     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8669     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8670
8671     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8672     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8673     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8674     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8675
8676     hr = IDirect3DDevice9_BeginScene(device);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8678     if(SUCCEEDED(hr)) {
8679
8680         hr = IDirect3DDevice9_EndScene(device);
8681         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8682         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8683         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8684     }
8685     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8686     color = getPixelColor(device, 320, 240);
8687     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8688
8689     /* Set stage 1 back to default */
8690     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8691     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8692     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8693     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8694     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8695     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8696     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8697     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8698     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8699     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8700 }
8701
8702 struct testdata
8703 {
8704     DWORD idxVertex; /* number of instances in the first stream */
8705     DWORD idxColor; /* number of instances in the second stream */
8706     DWORD idxInstance; /* should be 1 ?? */
8707     DWORD color1; /* color 1 instance */
8708     DWORD color2; /* color 2 instance */
8709     DWORD color3; /* color 3 instance */
8710     DWORD color4; /* color 4 instance */
8711     WORD strVertex; /* specify which stream to use 0-2*/
8712     WORD strColor;
8713     WORD strInstance;
8714 };
8715
8716 static const struct testdata testcases[]=
8717 {
8718     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8719     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8720     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8721     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8722     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8723     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8724     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8725     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8726     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8727     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8728     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8729     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8730     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8731     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8732     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8733 /*
8734     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8735     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8736 */
8737 };
8738
8739 /* Drawing Indexed Geometry with instances*/
8740 static void stream_test(IDirect3DDevice9 *device)
8741 {
8742     IDirect3DVertexBuffer9 *vb = NULL;
8743     IDirect3DVertexBuffer9 *vb2 = NULL;
8744     IDirect3DVertexBuffer9 *vb3 = NULL;
8745     IDirect3DIndexBuffer9 *ib = NULL;
8746     IDirect3DVertexDeclaration9 *pDecl = NULL;
8747     IDirect3DVertexShader9 *shader = NULL;
8748     HRESULT hr;
8749     BYTE *data;
8750     DWORD color;
8751     DWORD ind;
8752     int i;
8753
8754     const DWORD shader_code[] =
8755     {
8756         0xfffe0101,                                     /* vs_1_1 */
8757         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
8758         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
8759         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
8760         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
8761         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8762         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
8763         0x0000ffff
8764     };
8765
8766     const float quad[][3] =
8767     {
8768         {-0.5f, -0.5f,  1.1f}, /*0 */
8769         {-0.5f,  0.5f,  1.1f}, /*1 */
8770         { 0.5f, -0.5f,  1.1f}, /*2 */
8771         { 0.5f,  0.5f,  1.1f}, /*3 */
8772     };
8773
8774     const float vertcolor[][4] =
8775     {
8776         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8777         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8778         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8779         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8780     };
8781
8782     /* 4 position for 4 instances */
8783     const float instancepos[][3] =
8784     {
8785         {-0.6f,-0.6f, 0.0f},
8786         { 0.6f,-0.6f, 0.0f},
8787         { 0.6f, 0.6f, 0.0f},
8788         {-0.6f, 0.6f, 0.0f},
8789     };
8790
8791     short indices[] = {0, 1, 2, 1, 2, 3};
8792
8793     D3DVERTEXELEMENT9 decl[] =
8794     {
8795         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8796         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8797         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8798         D3DDECL_END()
8799     };
8800
8801     /* set the default value because it isn't done in wine? */
8802     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8803     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8804
8805     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8806     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8807     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8808
8809     /* check wrong cases */
8810     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8811     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8812     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8813     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8814     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8815     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8816     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8817     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8818     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8819     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8820     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8821     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8822     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8823     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8824     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8825     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8826     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8827     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8828     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8829     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8830
8831     /* set the default value back */
8832     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8833     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8834
8835     /* create all VertexBuffers*/
8836     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8837     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8838     if(!vb) {
8839         skip("Failed to create a vertex buffer\n");
8840         return;
8841     }
8842     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8843     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8844     if(!vb2) {
8845         skip("Failed to create a vertex buffer\n");
8846         goto out;
8847     }
8848     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8849     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8850     if(!vb3) {
8851         skip("Failed to create a vertex buffer\n");
8852         goto out;
8853     }
8854
8855     /* create IndexBuffer*/
8856     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8857     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8858     if(!ib) {
8859         skip("Failed to create a index buffer\n");
8860         goto out;
8861     }
8862
8863     /* copy all Buffers (Vertex + Index)*/
8864     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8865     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8866     memcpy(data, quad, sizeof(quad));
8867     hr = IDirect3DVertexBuffer9_Unlock(vb);
8868     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8869     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8870     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8871     memcpy(data, vertcolor, sizeof(vertcolor));
8872     hr = IDirect3DVertexBuffer9_Unlock(vb2);
8873     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8874     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8875     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8876     memcpy(data, instancepos, sizeof(instancepos));
8877     hr = IDirect3DVertexBuffer9_Unlock(vb3);
8878     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8879     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8880     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8881     memcpy(data, indices, sizeof(indices));
8882     hr = IDirect3DIndexBuffer9_Unlock(ib);
8883     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8884
8885     /* create VertexShader */
8886     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8887     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8888     if(!shader) {
8889         skip("Failed to create a vetex shader\n");
8890         goto out;
8891     }
8892
8893     hr = IDirect3DDevice9_SetVertexShader(device, shader);
8894     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8895
8896     hr = IDirect3DDevice9_SetIndices(device, ib);
8897     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8898
8899     /* run all tests */
8900     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8901     {
8902         struct testdata act = testcases[i];
8903         decl[0].Stream = act.strVertex;
8904         decl[1].Stream = act.strColor;
8905         decl[2].Stream = act.strInstance;
8906         /* create VertexDeclarations */
8907         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8908         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8909
8910         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8911         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8912
8913         hr = IDirect3DDevice9_BeginScene(device);
8914         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8915         if(SUCCEEDED(hr))
8916         {
8917             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8918             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8919
8920             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8921             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8922             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8923             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8924
8925             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8926             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8927             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8928             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8929
8930             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8931             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8932             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8933             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8934
8935             /* don't know if this is right (1*3 and 4*1)*/
8936             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8937             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8938             hr = IDirect3DDevice9_EndScene(device);
8939             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8940
8941             /* set all StreamSource && StreamSourceFreq back to default */
8942             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8943             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8944             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8945             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8946             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8947             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8948             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8949             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8950             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8951             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8952             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8953             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8954         }
8955
8956         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8957         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8958
8959         hr = IDirect3DVertexDeclaration9_Release(pDecl);
8960         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8961
8962         color = getPixelColor(device, 160, 360);
8963         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8964         color = getPixelColor(device, 480, 360);
8965         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8966         color = getPixelColor(device, 480, 120);
8967         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8968         color = getPixelColor(device, 160, 120);
8969         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8970     }
8971
8972     hr = IDirect3DDevice9_SetIndices(device, NULL);
8973     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8974
8975 out:
8976     if(vb) IDirect3DVertexBuffer9_Release(vb);
8977     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8978     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8979     if(ib)IDirect3DIndexBuffer9_Release(ib);
8980     if(shader)IDirect3DVertexShader9_Release(shader);
8981 }
8982
8983 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8984     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8985     IDirect3DTexture9 *dsttex = NULL;
8986     HRESULT hr;
8987     DWORD color;
8988     D3DRECT r1 = {0,  0,  50,  50 };
8989     D3DRECT r2 = {50, 0,  100, 50 };
8990     D3DRECT r3 = {50, 50, 100, 100};
8991     D3DRECT r4 = {0,  50,  50, 100};
8992     const float quad[] = {
8993         -1.0,   -1.0,   0.1,    0.0,    0.0,
8994          1.0,   -1.0,   0.1,    1.0,    0.0,
8995         -1.0,    1.0,   0.1,    0.0,    1.0,
8996          1.0,    1.0,   0.1,    1.0,    1.0,
8997     };
8998
8999     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9000     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
9001
9002     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9003     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
9004     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9005     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
9006
9007     if(!src || !dsttex) {
9008         skip("One or more test resources could not be created\n");
9009         goto cleanup;
9010     }
9011
9012     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9013     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
9014
9015     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9016     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9017
9018     /* Clear the StretchRect destination for debugging */
9019     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9020     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9021     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9022     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9023
9024     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9025     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9026
9027     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9028     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9029     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9030     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9031     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9032     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9033     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9034     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9035
9036     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9037      * the target -> texture GL blit path
9038      */
9039     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9040     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9041     IDirect3DSurface9_Release(dst);
9042
9043     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9044     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9045
9046     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9048     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9050     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9051     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9052     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9053     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9054
9055     hr = IDirect3DDevice9_BeginScene(device);
9056     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9057     if(SUCCEEDED(hr)) {
9058         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9059         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9060         hr = IDirect3DDevice9_EndScene(device);
9061         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9062     }
9063
9064     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9065     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9066     color = getPixelColor(device, 160, 360);
9067     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9068     color = getPixelColor(device, 480, 360);
9069     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9070     color = getPixelColor(device, 480, 120);
9071     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9072     color = getPixelColor(device, 160, 120);
9073     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9074
9075     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9076     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9077     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9078     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9079
9080 cleanup:
9081     if(src) IDirect3DSurface9_Release(src);
9082     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9083     if(dsttex) IDirect3DTexture9_Release(dsttex);
9084 }
9085
9086 START_TEST(visual)
9087 {
9088     IDirect3DDevice9 *device_ptr;
9089     D3DCAPS9 caps;
9090     HRESULT hr;
9091     DWORD color;
9092
9093     d3d9_handle = LoadLibraryA("d3d9.dll");
9094     if (!d3d9_handle)
9095     {
9096         skip("Could not load d3d9.dll\n");
9097         return;
9098     }
9099
9100     device_ptr = init_d3d9();
9101     if (!device_ptr)
9102     {
9103         skip("Creating the device failed\n");
9104         return;
9105     }
9106
9107     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9108
9109     /* Check for the reliability of the returned data */
9110     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9111     if(FAILED(hr))
9112     {
9113         trace("Clear failed, can't assure correctness of the test results, skipping\n");
9114         goto cleanup;
9115     }
9116     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9117
9118     color = getPixelColor(device_ptr, 1, 1);
9119     if(color !=0x00ff0000)
9120     {
9121         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9122         goto cleanup;
9123     }
9124
9125     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9126     if(FAILED(hr))
9127     {
9128         trace("Clear failed, can't assure correctness of the test results, skipping\n");
9129         goto cleanup;
9130     }
9131     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9132
9133     color = getPixelColor(device_ptr, 639, 479);
9134     if(color != 0x0000ddee)
9135     {
9136         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9137         goto cleanup;
9138     }
9139
9140     /* Now execute the real tests */
9141     stretchrect_test(device_ptr);
9142     lighting_test(device_ptr);
9143     clear_test(device_ptr);
9144     fog_test(device_ptr);
9145     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9146     {
9147         test_cube_wrap(device_ptr);
9148     } else {
9149         skip("No cube texture support\n");
9150     }
9151     z_range_test(device_ptr);
9152     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9153     {
9154         maxmip_test(device_ptr);
9155     }
9156     else
9157     {
9158         skip("No mipmap support\n");
9159     }
9160     offscreen_test(device_ptr);
9161     alpha_test(device_ptr);
9162     shademode_test(device_ptr);
9163     srgbtexture_test(device_ptr);
9164     release_buffer_test(device_ptr);
9165     float_texture_test(device_ptr);
9166     g16r16_texture_test(device_ptr);
9167     pixelshader_blending_test(device_ptr);
9168     texture_transform_flags_test(device_ptr);
9169     autogen_mipmap_test(device_ptr);
9170     fixed_function_decl_test(device_ptr);
9171     conditional_np2_repeat_test(device_ptr);
9172     fixed_function_bumpmap_test(device_ptr);
9173     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9174         stencil_cull_test(device_ptr);
9175     } else {
9176         skip("No two sided stencil support\n");
9177     }
9178     pointsize_test(device_ptr);
9179     tssargtemp_test(device_ptr);
9180     np2_stretch_rect_test(device_ptr);
9181
9182     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9183     {
9184         test_constant_clamp_vs(device_ptr);
9185         test_compare_instructions(device_ptr);
9186     }
9187     else skip("No vs_1_1 support\n");
9188
9189     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9190     {
9191         test_mova(device_ptr);
9192         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9193             test_vshader_input(device_ptr);
9194             test_vshader_float16(device_ptr);
9195             stream_test(device_ptr);
9196         } else {
9197             skip("No vs_3_0 support\n");
9198         }
9199     }
9200     else skip("No vs_2_0 support\n");
9201
9202     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9203     {
9204         fog_with_shader_test(device_ptr);
9205         fog_srgbwrite_test(device_ptr);
9206     }
9207     else skip("No vs_1_1 and ps_1_1 support\n");
9208
9209     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9210     {
9211         texbem_test(device_ptr);
9212         texdepth_test(device_ptr);
9213         texkill_test(device_ptr);
9214         x8l8v8u8_test(device_ptr);
9215         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9216             constant_clamp_ps_test(device_ptr);
9217             cnd_test(device_ptr);
9218             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9219                 dp2add_ps_test(device_ptr);
9220                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9221                     nested_loop_test(device_ptr);
9222                     fixed_function_varying_test(device_ptr);
9223                     vFace_register_test(device_ptr);
9224                     vpos_register_test(device_ptr);
9225                     multiple_rendertargets_test(device_ptr);
9226                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9227                         vshader_version_varying_test(device_ptr);
9228                         pshader_version_varying_test(device_ptr);
9229                     } else {
9230                         skip("No vs_3_0 support\n");
9231                     }
9232                 } else {
9233                     skip("No ps_3_0 support\n");
9234                 }
9235             } else {
9236                 skip("No ps_2_0 support\n");
9237             }
9238         }
9239     }
9240     else skip("No ps_1_1 support\n");
9241
9242 cleanup:
9243     if(device_ptr) {
9244         ULONG ref;
9245
9246         D3DPRESENT_PARAMETERS present_parameters;
9247         IDirect3DSwapChain9 *swapchain;
9248         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9249         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9250         IDirect3DSwapChain9_Release(swapchain);
9251         ref = IDirect3DDevice9_Release(device_ptr);
9252         DestroyWindow(present_parameters.hDeviceWindow);
9253         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
9254     }
9255 }