d3d9: Fix a few ok() comparisons to not always return true in the visual tests.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007 Henri Verbeet
3  * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
21  * the framebuffer, read back from there and compared to expected colors.
22  *
23  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
24  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
25  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
26  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
27  * causes visible results in games can be tested in a way that does not depend on pixel exactness
28  */
29
30 #define COBJMACROS
31 #include <d3d9.h>
32 #include <dxerr9.h>
33 #include "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 static HWND create_window(void)
38 {
39     WNDCLASS wc = {0};
40     HWND ret;
41     wc.lpfnWndProc = &DefWindowProc;
42     wc.lpszClassName = "d3d9_test_wc";
43     RegisterClass(&wc);
44
45     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46                         WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47     return ret;
48 }
49
50 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
51 {
52     DWORD ret;
53     IDirect3DSurface9 *surf;
54     HRESULT hr;
55     D3DLOCKED_RECT lockedRect;
56     RECT rectToLock = {x, y, x+1, y+1};
57
58     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
59     if(FAILED(hr) || !surf )  /* This is not a test */
60     {
61         trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
62         return 0xdeadbeef;
63     }
64
65     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
66     if(FAILED(hr))
67     {
68         trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
69         ret = 0xdeadbeed;
70         goto out;
71     }
72
73     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
74     if(FAILED(hr))
75     {
76         trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
77         ret = 0xdeadbeec;
78         goto out;
79     }
80
81     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
82      * really important for these tests
83      */
84     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
85     hr = IDirect3DSurface9_UnlockRect(surf);
86     if(FAILED(hr))
87     {
88         trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
89     }
90
91 out:
92     if(surf) IDirect3DSurface9_Release(surf);
93     return ret;
94 }
95
96 static IDirect3DDevice9 *init_d3d9(void)
97 {
98     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
99     IDirect3D9 *d3d9_ptr = 0;
100     IDirect3DDevice9 *device_ptr = 0;
101     D3DPRESENT_PARAMETERS present_parameters;
102     HRESULT hr;
103
104     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
105     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
106     if (!d3d9_create) return NULL;
107
108     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
109     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
110     if (!d3d9_ptr) return NULL;
111
112     ZeroMemory(&present_parameters, sizeof(present_parameters));
113     present_parameters.Windowed = FALSE;
114     present_parameters.hDeviceWindow = create_window();
115     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
116     present_parameters.BackBufferWidth = 640;
117     present_parameters.BackBufferHeight = 480;
118     present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
119     present_parameters.EnableAutoDepthStencil = TRUE;
120     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
121
122     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
123     if(FAILED(hr)) {
124         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
125         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
126     }
127     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
128
129     return device_ptr;
130 }
131
132 struct vertex
133 {
134     float x, y, z;
135     DWORD diffuse;
136 };
137
138 struct tvertex
139 {
140     float x, y, z, rhw;
141     DWORD diffuse;
142 };
143
144 struct nvertex
145 {
146     float x, y, z;
147     float nx, ny, nz;
148     DWORD diffuse;
149 };
150
151 static void lighting_test(IDirect3DDevice9 *device)
152 {
153     HRESULT hr;
154     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
155     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
156     DWORD color;
157
158     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
159                       0.0f, 1.0f, 0.0f, 0.0f,
160                       0.0f, 0.0f, 1.0f, 0.0f,
161                       0.0f, 0.0f, 0.0f, 1.0f };
162
163     struct vertex unlitquad[] =
164     {
165         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
166         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
167         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
168         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
169     };
170     struct vertex litquad[] =
171     {
172         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
173         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
174         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
175         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
176     };
177     struct nvertex unlitnquad[] =
178     {
179         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
180         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
181         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
182         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
183     };
184     struct nvertex litnquad[] =
185     {
186         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
187         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
188         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
189         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
190     };
191     WORD Indices[] = {0, 1, 2, 2, 3, 0};
192
193     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
194     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
195
196     /* Setup some states that may cause issues */
197     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
198     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
199     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
200     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
201     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
202     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
203     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
204     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
205     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
206     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
207     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
208     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
209     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
210     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
211     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
212     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
213     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
214     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
215     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
216     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
217     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
218     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
219     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
220     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
221
222     hr = IDirect3DDevice9_SetFVF(device, fvf);
223     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
224
225     hr = IDirect3DDevice9_BeginScene(device);
226     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
227     if(hr == D3D_OK)
228     {
229         /* No lights are defined... That means, lit vertices should be entirely black */
230         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
231         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
232         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
233                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
234         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
235
236         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
237         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
238         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
239                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
240         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
241
242         hr = IDirect3DDevice9_SetFVF(device, nfvf);
243         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
244
245         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
246         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
247         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
248                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
249         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
250
251         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
252         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
253         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
254                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
255         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
256
257         IDirect3DDevice9_EndScene(device);
258         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
259     }
260
261     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
262
263     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
264     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
265     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
266     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
267     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
268     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
269     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
270     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
271
272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
274 }
275
276 static void clear_test(IDirect3DDevice9 *device)
277 {
278     /* Tests the correctness of clearing parameters */
279     HRESULT hr;
280     D3DRECT rect[2];
281     D3DRECT rect_negneg;
282     DWORD color;
283     D3DVIEWPORT9 old_vp, vp;
284     RECT scissor;
285     DWORD oldColorWrite;
286     BOOL invalid_clear_failed = FALSE;
287
288     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
289     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
290
291     /* Positive x, negative y */
292     rect[0].x1 = 0;
293     rect[0].y1 = 480;
294     rect[0].x2 = 320;
295     rect[0].y2 = 240;
296
297     /* Positive x, positive y */
298     rect[1].x1 = 0;
299     rect[1].y1 = 0;
300     rect[1].x2 = 320;
301     rect[1].y2 = 240;
302     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
303      * returns D3D_OK, but ignores the rectangle silently
304      */
305     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
306     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
307     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
308
309     /* negative x, negative y */
310     rect_negneg.x1 = 640;
311     rect_negneg.y1 = 240;
312     rect_negneg.x2 = 320;
313     rect_negneg.y2 = 0;
314     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
315     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
316     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
317
318     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
319
320     color = getPixelColor(device, 160, 360); /* lower left quad */
321     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
322     color = getPixelColor(device, 160, 120); /* upper left quad */
323     if(invalid_clear_failed) {
324         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
325         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
326     } else {
327         /* If the negative rectangle was dropped silently, the correct ones are cleared */
328         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
329     }
330     color = getPixelColor(device, 480, 360); /* lower right quad  */
331     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
332     color = getPixelColor(device, 480, 120); /* upper right quad */
333     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
334
335     /* Test how the viewport affects clears */
336     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
337     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
338     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
339     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
340
341     vp.X = 160;
342     vp.Y = 120;
343     vp.Width = 160;
344     vp.Height = 120;
345     vp.MinZ = 0.0;
346     vp.MaxZ = 1.0;
347     hr = IDirect3DDevice9_SetViewport(device, &vp);
348     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
349     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
350     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
351
352     vp.X = 320;
353     vp.Y = 240;
354     vp.Width = 320;
355     vp.Height = 240;
356     vp.MinZ = 0.0;
357     vp.MaxZ = 1.0;
358     hr = IDirect3DDevice9_SetViewport(device, &vp);
359     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
360     rect[0].x1 = 160;
361     rect[0].y1 = 120;
362     rect[0].x2 = 480;
363     rect[0].y2 = 360;
364     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
365     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
366
367     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
368     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
369
370     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
371     color = getPixelColor(device, 158, 118);
372     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
373     color = getPixelColor(device, 162, 118);
374     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
375     color = getPixelColor(device, 158, 122);
376     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
377     color = getPixelColor(device, 162, 122);
378     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
379
380     color = getPixelColor(device, 318, 238);
381     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
382     color = getPixelColor(device, 322, 238);
383     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
384     color = getPixelColor(device, 318, 242);
385     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
386     color = getPixelColor(device, 322, 242);
387     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
388
389     color = getPixelColor(device, 478, 358);
390     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
391     color = getPixelColor(device, 482, 358);
392     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
393     color = getPixelColor(device, 478, 362);
394     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
395     color = getPixelColor(device, 482, 362);
396     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
397
398     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
399     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
400
401     scissor.left = 160;
402     scissor.right = 480;
403     scissor.top = 120;
404     scissor.bottom = 360;
405     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
406     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
407     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
408     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
409
410     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
411     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
412     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
413     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
414
415     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
416     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
417
418     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419     color = getPixelColor(device, 158, 118);
420     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
421     color = getPixelColor(device, 162, 118);
422     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
423     color = getPixelColor(device, 158, 122);
424     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
425     color = getPixelColor(device, 162, 122);
426     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
427
428     color = getPixelColor(device, 158, 358);
429     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
430     color = getPixelColor(device, 162, 358);
431     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
432     color = getPixelColor(device, 158, 358);
433     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
434     color = getPixelColor(device, 162, 362);
435     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
436
437     color = getPixelColor(device, 478, 118);
438     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
439     color = getPixelColor(device, 478, 122);
440     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
441     color = getPixelColor(device, 482, 122);
442     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
443     color = getPixelColor(device, 482, 358);
444     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
445
446     color = getPixelColor(device, 478, 358);
447     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
448     color = getPixelColor(device, 478, 362);
449     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
450     color = getPixelColor(device, 482, 358);
451     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
452     color = getPixelColor(device, 482, 362);
453     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
454
455     color = getPixelColor(device, 318, 238);
456     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
457     color = getPixelColor(device, 318, 242);
458     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
459     color = getPixelColor(device, 322, 238);
460     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
461     color = getPixelColor(device, 322, 242);
462     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
463
464     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
465     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
466     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
467     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
468
469     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
470     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
471
472     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
473     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
474
475     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
476
477     /* Colorwriteenable does not affect the clear */
478     color = getPixelColor(device, 320, 240);
479     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
480 }
481
482 typedef struct {
483     float in[4];
484     DWORD out;
485 } test_data_t;
486
487 /*
488  *  c7      mova    ARGB            mov     ARGB
489  * -2.4     -2      0x00ffff00      -3      0x00ff0000
490  * -1.6     -2      0x00ffff00      -2      0x00ffff00
491  * -0.4      0      0x0000ffff      -1      0x0000ff00
492  *  0.4      0      0x0000ffff       0      0x0000ffff
493  *  1.6      2      0x00ff00ff       1      0x000000ff
494  *  2.4      2      0x00ff00ff       2      0x00ff00ff
495  */
496 static void test_mova(IDirect3DDevice9 *device)
497 {
498     static const DWORD mova_test[] = {
499         0xfffe0200,                                                             /* vs_2_0                       */
500         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
501         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
502         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
503         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
504         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
505         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
506         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
507         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
508         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
509         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
510         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
511         0x0000ffff                                                              /* END                          */
512     };
513     static const DWORD mov_test[] = {
514         0xfffe0101,                                                             /* vs_1_1                       */
515         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
516         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
517         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
518         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
519         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
520         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
521         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
522         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
523         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
524         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
525         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
526         0x0000ffff                                                              /* END                          */
527     };
528
529     static const test_data_t test_data[2][6] = {
530         {
531             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
532             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
533             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
534             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
535             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
536             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
537         },
538         {
539             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
540             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
541             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
542             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
543             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
544             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
545         }
546     };
547
548     static const float quad[][3] = {
549         {-1.0f, -1.0f, 0.0f},
550         {-1.0f,  1.0f, 0.0f},
551         { 1.0f, -1.0f, 0.0f},
552         { 1.0f,  1.0f, 0.0f},
553     };
554
555     static const D3DVERTEXELEMENT9 decl_elements[] = {
556         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
557         D3DDECL_END()
558     };
559
560     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
561     IDirect3DVertexShader9 *mova_shader = NULL;
562     IDirect3DVertexShader9 *mov_shader = NULL;
563     HRESULT hr;
564     UINT i, j;
565
566     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
567     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
568     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
569     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
570     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
571     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
572     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
573     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
574
575     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
576     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
577     for(j = 0; j < 2; ++j)
578     {
579         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
580         {
581             DWORD color;
582
583             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
584             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
585
586             hr = IDirect3DDevice9_BeginScene(device);
587             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
588
589             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
590             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
591
592             hr = IDirect3DDevice9_EndScene(device);
593             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
594
595             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
596             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
597
598             color = getPixelColor(device, 320, 240);
599             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
600                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
601
602             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
603             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
604         }
605         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
606         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
607     }
608
609     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
610     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
611
612     IDirect3DVertexDeclaration9_Release(vertex_declaration);
613     IDirect3DVertexShader9_Release(mova_shader);
614     IDirect3DVertexShader9_Release(mov_shader);
615 }
616
617 struct sVertex {
618     float x, y, z;
619     DWORD diffuse;
620     DWORD specular;
621 };
622
623 struct sVertexT {
624     float x, y, z, rhw;
625     DWORD diffuse;
626     DWORD specular;
627 };
628
629 static void fog_test(IDirect3DDevice9 *device)
630 {
631     HRESULT hr;
632     DWORD color;
633     BYTE r, g, b;
634     float start = 0.0f, end = 1.0f;
635     D3DCAPS9 caps;
636     int i;
637
638     /* Gets full z based fog with linear fog, no fog with specular color */
639     struct sVertex unstransformed_1[] = {
640         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
641         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
642         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
643         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
644     };
645     /* Ok, I am too lazy to deal with transform matrices */
646     struct sVertex unstransformed_2[] = {
647         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
648         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
649         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
650         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
651     };
652     /* Untransformed ones. Give them a different diffuse color to make the test look
653      * nicer. It also makes making sure that they are drawn correctly easier.
654      */
655     struct sVertexT transformed_1[] = {
656         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
657         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
658         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
659         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
660     };
661     struct sVertexT transformed_2[] = {
662         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
663         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
664         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
665         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
666     };
667     struct vertex rev_fog_quads[] = {
668        {-1.0,   -1.0,   0.1,    0x000000ff},
669        {-1.0,    0.0,   0.1,    0x000000ff},
670        { 0.0,    0.0,   0.1,    0x000000ff},
671        { 0.0,   -1.0,   0.1,    0x000000ff},
672
673        { 0.0,   -1.0,   0.9,    0x000000ff},
674        { 0.0,    0.0,   0.9,    0x000000ff},
675        { 1.0,    0.0,   0.9,    0x000000ff},
676        { 1.0,   -1.0,   0.9,    0x000000ff},
677
678        { 0.0,    0.0,   0.4,    0x000000ff},
679        { 0.0,    1.0,   0.4,    0x000000ff},
680        { 1.0,    1.0,   0.4,    0x000000ff},
681        { 1.0,    0.0,   0.4,    0x000000ff},
682
683        {-1.0,    0.0,   0.7,    0x000000ff},
684        {-1.0,    1.0,   0.7,    0x000000ff},
685        { 0.0,    1.0,   0.7,    0x000000ff},
686        { 0.0,    0.0,   0.7,    0x000000ff},
687     };
688     WORD Indices[] = {0, 1, 2, 2, 3, 0};
689
690     memset(&caps, 0, sizeof(caps));
691     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
692     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
693     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
694     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
695
696     /* Setup initial states: No lighting, fog on, fog color */
697     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
698     ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
699     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
700     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
701     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
702     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
703
704     /* First test: Both table fog and vertex fog off */
705     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
706     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
707     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
708     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
709
710     /* Start = 0, end = 1. Should be default, but set them */
711     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
712     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
714     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
715
716     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
717     {
718         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
719         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
720         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
721         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
722                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
723                                                      sizeof(unstransformed_1[0]));
724         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
725
726         /* That makes it use the Z value */
727         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
728         ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
729         /* Untransformed, vertex fog != none (or table fog != none):
730          * Use the Z value as input into the equation
731          */
732         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
733                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
734                                                      sizeof(unstransformed_1[0]));
735         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
736
737         /* transformed verts */
738         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
739         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
740         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
741         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
742                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
743                                                      sizeof(transformed_1[0]));
744         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
745
746         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
747         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
748         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
749          * equation
750          */
751         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
752                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
753                                                      sizeof(transformed_2[0]));
754
755         hr = IDirect3DDevice9_EndScene(device);
756         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
757     }
758     else
759     {
760         ok(FALSE, "BeginScene failed\n");
761     }
762
763     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
764     color = getPixelColor(device, 160, 360);
765     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
766     color = getPixelColor(device, 160, 120);
767     ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
768     color = getPixelColor(device, 480, 120);
769     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
770     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
771     {
772         color = getPixelColor(device, 480, 360);
773         ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
774     }
775     else
776     {
777         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
778          * The settings above result in no fogging with vertex fog
779          */
780         color = getPixelColor(device, 480, 120);
781         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
782         trace("Info: Table fog not supported by this device\n");
783     }
784
785     /* Now test the special case fogstart == fogend */
786     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
787     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
788
789     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
790     {
791         start = 512;
792         end = 512;
793         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
794         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
795         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
796         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
797
798         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
799         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
800         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
801         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
802         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
803         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
804
805         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
806          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
807          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
808          * The third transformed quad remains unfogged because the fogcoords are read from the specular
809          * color and has fixed fogstart and fogend.
810          */
811         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
812                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
813                 sizeof(unstransformed_1[0]));
814         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
815         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
816                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
817                 sizeof(unstransformed_1[0]));
818         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
819
820         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
821         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
822         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
823         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
824                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
825                 sizeof(transformed_1[0]));
826         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
827
828         hr = IDirect3DDevice9_EndScene(device);
829         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
830     }
831     else
832     {
833         ok(FALSE, "BeginScene failed\n");
834     }
835     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
836     color = getPixelColor(device, 160, 360);
837     ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
838     color = getPixelColor(device, 160, 120);
839     ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
840     color = getPixelColor(device, 480, 120);
841     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
842
843     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
844      * but without shaders it seems to work everywhere
845      */
846     end = 0.2;
847     start = 0.8;
848     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
849     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
850     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
851     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
852     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
853     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
854
855     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
856      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
857      * so skip this for now
858      */
859     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
860         const char *mode = (i ? "table" : "vertex");
861         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
862         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
863         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
864         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
865         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
866         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
867         hr = IDirect3DDevice9_BeginScene(device);
868         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
869         if(SUCCEEDED(hr)) {
870             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
871                                 4,  5,  6,  6,  7, 4,
872                                 8,  9, 10, 10, 11, 8,
873                             12, 13, 14, 14, 15, 12};
874
875             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
876                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
877                     sizeof(rev_fog_quads[0]));
878
879             hr = IDirect3DDevice9_EndScene(device);
880             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
881         }
882         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
883         color = getPixelColor(device, 160, 360);
884         ok(color == 0x0000FF00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
885
886         color = getPixelColor(device, 160, 120);
887         r = (color & 0x00ff0000) >> 16;
888         g = (color & 0x0000ff00) >>  8;
889         b = (color & 0x000000ff);
890         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
891            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
892
893         color = getPixelColor(device, 480, 120);
894         r = (color & 0x00ff0000) >> 16;
895         g = (color & 0x0000ff00) >>  8;
896         b = (color & 0x000000ff);
897         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
898            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
899
900         color = getPixelColor(device, 480, 360);
901         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
902
903         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
904             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
905             break;
906         }
907     }
908     /* Turn off the fog master switch to avoid confusing other tests */
909     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
910     ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
911     start = 0.0;
912     end = 1.0;
913     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
914     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
915     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
916     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
917     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
918     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
919     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
920     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
921 }
922
923 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
924  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
925  * regardless of the actual addressing mode set. */
926 static void test_cube_wrap(IDirect3DDevice9 *device)
927 {
928     static const float quad[][6] = {
929         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
930         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
931         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
932         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
933     };
934
935     static const D3DVERTEXELEMENT9 decl_elements[] = {
936         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
937         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
938         D3DDECL_END()
939     };
940
941     static const struct {
942         D3DTEXTUREADDRESS mode;
943         const char *name;
944     } address_modes[] = {
945         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
946         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
947         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
948         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
949         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
950     };
951
952     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
953     IDirect3DCubeTexture9 *texture = NULL;
954     IDirect3DSurface9 *surface = NULL;
955     D3DLOCKED_RECT locked_rect;
956     HRESULT hr;
957     UINT x;
958     INT y, face;
959
960     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
961     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
962     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
963     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
964
965     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
966             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
967     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
968
969     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
970     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
971
972     for (y = 0; y < 128; ++y)
973     {
974         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
975         for (x = 0; x < 64; ++x)
976         {
977             *ptr++ = 0xffff0000;
978         }
979         for (x = 64; x < 128; ++x)
980         {
981             *ptr++ = 0xff0000ff;
982         }
983     }
984
985     hr = IDirect3DSurface9_UnlockRect(surface);
986     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
987
988     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
989             D3DPOOL_DEFAULT, &texture, NULL);
990     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
991
992     /* Create cube faces */
993     for (face = 0; face < 6; ++face)
994     {
995         IDirect3DSurface9 *face_surface = NULL;
996
997         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
998         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
999
1000         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1001         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1002
1003         IDirect3DSurface9_Release(face_surface);
1004     }
1005
1006     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1007     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1008
1009     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1010     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1011     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1012     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1013     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1014     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1015
1016     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1017     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1018
1019     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1020     {
1021         DWORD color;
1022
1023         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1024         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1025         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1026         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1027
1028         hr = IDirect3DDevice9_BeginScene(device);
1029         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1030
1031         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1032         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1033
1034         hr = IDirect3DDevice9_EndScene(device);
1035         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1036
1037         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1038         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1039
1040         /* Due to the nature of this test, we sample essentially at the edge
1041          * between two faces. Because of this it's undefined from which face
1042          * the driver will sample. Furtunately that's not important for this
1043          * test, since all we care about is that it doesn't sample from the
1044          * other side of the surface or from the border. */
1045         color = getPixelColor(device, 320, 240);
1046         ok(color == 0x00ff0000 || color == 0x000000ff,
1047                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1048                 color, address_modes[x].name);
1049
1050         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1051         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1052     }
1053
1054     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1055     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1056
1057     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1058     IDirect3DCubeTexture9_Release(texture);
1059     IDirect3DSurface9_Release(surface);
1060 }
1061
1062 static void offscreen_test(IDirect3DDevice9 *device)
1063 {
1064     HRESULT hr;
1065     IDirect3DTexture9 *offscreenTexture = NULL;
1066     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1067     DWORD color;
1068
1069     static const float quad[][5] = {
1070         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1071         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1072         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1073         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1074     };
1075
1076     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1077     ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1078
1079     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1080     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1081     if(!offscreenTexture) {
1082         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1083         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1084         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1085         if(!offscreenTexture) {
1086             skip("Cannot create an offscreen render target\n");
1087             goto out;
1088         }
1089     }
1090
1091     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1092     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1093     if(!backbuffer) {
1094         goto out;
1095     }
1096
1097     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1098     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1099     if(!offscreen) {
1100         goto out;
1101     }
1102
1103     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1104     ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1105
1106     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1107     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1108     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1109     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1110     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1111     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1112     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1113     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1114     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1115     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1116
1117     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1118         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1119         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1120         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1121         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1122
1123         /* Draw without textures - Should resut in a white quad */
1124         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1125         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1126
1127         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1128         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1129         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1130         ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1131
1132         /* This time with the texture */
1133         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1134         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1135
1136         IDirect3DDevice9_EndScene(device);
1137     }
1138
1139     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1140
1141     /* Center quad - should be white */
1142     color = getPixelColor(device, 320, 240);
1143     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1144     /* Some quad in the cleared part of the texture */
1145     color = getPixelColor(device, 170, 240);
1146     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1147     /* Part of the originally cleared back buffer */
1148     color = getPixelColor(device, 10, 10);
1149     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1150     if(0) {
1151         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1152          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1153          * the offscreen rendering mode this test would succeed or fail
1154          */
1155         color = getPixelColor(device, 10, 470);
1156         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1157     }
1158
1159 out:
1160     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1161
1162     /* restore things */
1163     if(backbuffer) {
1164         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1165         IDirect3DSurface9_Release(backbuffer);
1166     }
1167     if(offscreenTexture) {
1168         IDirect3DTexture9_Release(offscreenTexture);
1169     }
1170     if(offscreen) {
1171         IDirect3DSurface9_Release(offscreen);
1172     }
1173 }
1174
1175 /* This test tests fog in combination with shaders.
1176  * What's tested: linear fog (vertex and table) with pixel shader
1177  *                linear table fog with non foggy vertex shader
1178  *                vertex fog with foggy vertex shader
1179  * What's not tested: non linear fog with shader
1180  *                    table fog with foggy vertex shader
1181  */
1182 static void fog_with_shader_test(IDirect3DDevice9 *device)
1183 {
1184     HRESULT hr;
1185     DWORD color;
1186     union {
1187         float f;
1188         DWORD i;
1189     } start, end;
1190     unsigned int i, j;
1191
1192     /* basic vertex shader without fog computation ("non foggy") */
1193     static const DWORD vertex_shader_code1[] = {
1194         0xfffe0101,                                                             /* vs_1_1                       */
1195         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1196         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1197         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1198         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1199         0x0000ffff
1200     };
1201     /* basic vertex shader with reversed fog computation ("foggy") */
1202     static const DWORD vertex_shader_code2[] = {
1203         0xfffe0101,                                                             /* vs_1_1                        */
1204         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1205         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1206         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1207         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1208         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1209         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1210         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1211         0x0000ffff
1212     };
1213     /* basic pixel shader */
1214     static const DWORD pixel_shader_code[] = {
1215         0xffff0101,                                                             /* ps_1_1     */
1216         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1217         0x0000ffff
1218     };
1219
1220     static struct vertex quad[] = {
1221         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1222         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1223         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1224         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1225     };
1226
1227     static const D3DVERTEXELEMENT9 decl_elements[] = {
1228         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1229         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1230         D3DDECL_END()
1231     };
1232
1233     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1234     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1235     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1236
1237     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1238     static const struct test_data_t {
1239         int vshader;
1240         int pshader;
1241         D3DFOGMODE vfog;
1242         D3DFOGMODE tfog;
1243         unsigned int color[11];
1244     } test_data[] = {
1245         /* only pixel shader: */
1246         {0, 1, 0, 3,
1247         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1248         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1249         {0, 1, 1, 3,
1250         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1251         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1252         {0, 1, 2, 3,
1253         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1254         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1255         {0, 1, 3, 0,
1256         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1257         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1258         {0, 1, 3, 3,
1259         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1260         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1261
1262         /* vertex shader */
1263         {1, 0, 0, 0,
1264         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1265          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1266         {1, 0, 0, 3,
1267         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1268         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1269         {1, 0, 1, 3,
1270         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1271         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1272
1273         {1, 0, 2, 3,
1274         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1275         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1276         {1, 0, 3, 3,
1277         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1278         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1279
1280         /* vertex shader and pixel shader */
1281         {1, 1, 0, 3,
1282         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1283         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1284         {1, 1, 1, 3,
1285         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1286         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1287         {1, 1, 2, 3,
1288         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1289         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1290
1291         {1, 1, 3, 3,
1292         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1293         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1294
1295
1296 #if 0  /* FIXME: these fail on GeForce 8500 */
1297         /* foggy vertex shader */
1298         {2, 0, 0, 0,
1299         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1300          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1301         {2, 0, 1, 0,
1302         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1303          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1304         {2, 0, 2, 0,
1305         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1306          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1307         {2, 0, 3, 0,
1308         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1309          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1310 #endif
1311
1312         /* foggy vertex shader and pixel shader */
1313         {2, 1, 0, 0,
1314         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1315          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1316         {2, 1, 1, 0,
1317         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1318          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1319         {2, 1, 2, 0,
1320         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1321          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1322         {2, 1, 3, 0,
1323         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1324          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1325
1326     };
1327
1328     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1329     start.f=0.1f;
1330     end.f=0.9f;
1331
1332     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1333     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1334     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1335     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1336     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1337     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1338     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1339     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1340
1341     /* Setup initial states: No lighting, fog on, fog color */
1342     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1343     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1344     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1345     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1346     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1347     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1348     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1349     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1350
1351     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1352     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1353     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1354     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1355
1356     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1357     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1358     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1359     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1360     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1361
1362     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1363     {
1364         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1365         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1366         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1367         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1368         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1369         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1370         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1371         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1372
1373         for(j=0; j < 11; j++)
1374         {
1375             /* Don't use the whole zrange to prevent rounding errors */
1376             quad[0].z = 0.001f + (float)j / 10.02f;
1377             quad[1].z = 0.001f + (float)j / 10.02f;
1378             quad[2].z = 0.001f + (float)j / 10.02f;
1379             quad[3].z = 0.001f + (float)j / 10.02f;
1380
1381             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1382             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1383
1384             hr = IDirect3DDevice9_BeginScene(device);
1385             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1386
1387             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1388             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1389
1390             hr = IDirect3DDevice9_EndScene(device);
1391             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1392
1393             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1394
1395             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1396             color = getPixelColor(device, 128, 240);
1397             ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1398                     && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1399                     && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1400                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1401                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1402         }
1403     }
1404
1405     /* reset states */
1406     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1407     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1408     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1409     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1410     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1411     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1412     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1413     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1414
1415     IDirect3DVertexShader9_Release(vertex_shader[1]);
1416     IDirect3DVertexShader9_Release(vertex_shader[2]);
1417     IDirect3DPixelShader9_Release(pixel_shader[1]);
1418     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1419 }
1420
1421 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1422     unsigned int i, x, y;
1423     HRESULT hr;
1424     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1425     D3DLOCKED_RECT locked_rect;
1426
1427     /* Generate the textures */
1428     for(i=0; i<2; i++)
1429     {
1430         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1431                                             D3DPOOL_MANAGED, &texture[i], NULL);
1432         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1433
1434         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1435         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1436         for (y = 0; y < 128; ++y)
1437         {
1438             if(i)
1439             { /* Set up black texture with 2x2 texel white spot in the middle */
1440                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1441                 for (x = 0; x < 128; ++x)
1442                 {
1443                     if(y>62 && y<66 && x>62 && x<66)
1444                         *ptr++ = 0xffffffff;
1445                     else
1446                         *ptr++ = 0xff000000;
1447                 }
1448             }
1449             else
1450             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1451                * (if multiplied with bumpenvmat)
1452               */
1453                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1454                 for (x = 0; x < 128; ++x)
1455                 {
1456                     if(abs(x-64)>abs(y-64))
1457                     {
1458                         if(x < 64)
1459                             *ptr++ = 0xc000;
1460                         else
1461                             *ptr++ = 0x4000;
1462                     }
1463                     else
1464                     {
1465                         if(y < 64)
1466                             *ptr++ = 0x0040;
1467                         else
1468                             *ptr++ = 0x00c0;
1469                     }
1470                 }
1471             }
1472         }
1473         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1474         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1475
1476         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1477         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1478
1479         /* Disable texture filtering */
1480         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1481         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1482         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1483         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1484
1485         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1486         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1487         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1488         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1489     }
1490 }
1491
1492 /* test the behavior of the texbem instruction
1493  * with normal 2D and projective 2D textures
1494  */
1495 static void texbem_test(IDirect3DDevice9 *device)
1496 {
1497     HRESULT hr;
1498     DWORD color;
1499     int i;
1500
1501     static const DWORD pixel_shader_code[] = {
1502         0xffff0101,                         /* ps_1_1*/
1503         0x00000042, 0xb00f0000,             /* tex t0*/
1504         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1505         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1506         0x0000ffff
1507     };
1508     static const DWORD double_texbem_code[] =  {
1509         0xffff0103,                                         /* ps_1_3           */
1510         0x00000042, 0xb00f0000,                             /* tex t0           */
1511         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1512         0x00000042, 0xb00f0002,                             /* tex t2           */
1513         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1514         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1515         0x0000ffff                                          /* end              */
1516     };
1517
1518
1519     static const float quad[][7] = {
1520         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1521         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1522         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1523         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1524     };
1525     static const float quad_proj[][9] = {
1526         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1527         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1528         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1529         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1530     };
1531
1532     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1533         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1534         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1535         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1536         D3DDECL_END()
1537     },{
1538         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1539         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1540         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1541         D3DDECL_END()
1542     } };
1543
1544     /* use assymetric matrix to test loading */
1545     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1546
1547     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1548     IDirect3DPixelShader9       *pixel_shader       = NULL;
1549     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1550     D3DLOCKED_RECT locked_rect;
1551
1552     generate_bumpmap_textures(device);
1553
1554     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1555     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1556     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1557     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1558     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1559
1560     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1561     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1562
1563     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1564     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1565
1566     for(i=0; i<2; i++)
1567     {
1568         if(i)
1569         {
1570             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1571             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1572         }
1573
1574         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1575         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1576         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1577         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1578
1579         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1580         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1581         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1582         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1583
1584         hr = IDirect3DDevice9_BeginScene(device);
1585         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1586
1587         if(!i)
1588             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1589         else
1590             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1591         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1592
1593         hr = IDirect3DDevice9_EndScene(device);
1594         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1595
1596         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1597         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1598
1599         color = getPixelColor(device, 320-32, 240);
1600         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1601         color = getPixelColor(device, 320+32, 240);
1602         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1603         color = getPixelColor(device, 320, 240-32);
1604         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1605         color = getPixelColor(device, 320, 240+32);
1606         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1607
1608         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1609         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1610         IDirect3DPixelShader9_Release(pixel_shader);
1611
1612         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1613         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1614         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1615     }
1616
1617     /* clean up */
1618     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1619     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1620
1621     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1622     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1623
1624     for(i=0; i<2; i++)
1625     {
1626         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1627         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1628         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1629         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1630         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1631         IDirect3DTexture9_Release(texture);
1632     }
1633
1634     /* Test double texbem */
1635     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1636     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1637     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1638     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1639     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1640     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1641     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1642     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1643
1644     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1645     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1646     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1647     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1648
1649     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1650     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1651
1652     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1653     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1654     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1655     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1656     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1657     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1658
1659     {
1660         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1661 #define tex  0x00ff0000
1662 #define tex1 0x0000ff00
1663 #define origin 0x000000ff
1664         static const DWORD pixel_data[] = {
1665             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1666             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1667             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1668             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1669             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1670             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1671             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1672             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1673         };
1674 #undef tex1
1675 #undef tex2
1676 #undef origin
1677
1678         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1679         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1680         for(i = 0; i < 8; i++) {
1681             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1682         }
1683         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1684         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1685     }
1686
1687     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1688     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1689     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1690     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1691     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1692     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1693     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1694     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1695     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1696     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1697     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1698     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1699
1700     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1701     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1702     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1703     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1704     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1705     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1706
1707     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1708     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1709     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1710     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1711     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1712     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1713
1714     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1715     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1716     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1717     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1718     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1719     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1720     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1721     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1722
1723     hr = IDirect3DDevice9_BeginScene(device);
1724     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1725     if(SUCCEEDED(hr)) {
1726         static const float double_quad[] = {
1727             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1728              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1729             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1730              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1731         };
1732
1733         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1734         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1735         hr = IDirect3DDevice9_EndScene(device);
1736         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1737     }
1738     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1739     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1740     color = getPixelColor(device, 320, 240);
1741     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1742
1743     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1744     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1745     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1746     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1747     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1748     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1749     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1750     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1751     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1752     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1753
1754     IDirect3DPixelShader9_Release(pixel_shader);
1755     IDirect3DTexture9_Release(texture);
1756     IDirect3DTexture9_Release(texture1);
1757     IDirect3DTexture9_Release(texture2);
1758 }
1759
1760 static void z_range_test(IDirect3DDevice9 *device)
1761 {
1762     const struct vertex quad[] =
1763     {
1764         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1765         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1766         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1767         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1768     };
1769     const struct vertex quad2[] =
1770     {
1771         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1772         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1773         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1774         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1775     };
1776
1777     const struct tvertex quad3[] =
1778     {
1779         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1780         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1781         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1782         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1783     };
1784     const struct tvertex quad4[] =
1785     {
1786         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1787         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1788         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1789         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1790     };
1791     HRESULT hr;
1792     DWORD color;
1793     IDirect3DVertexShader9 *shader;
1794     IDirect3DVertexDeclaration9 *decl;
1795     D3DCAPS9 caps;
1796     const DWORD shader_code[] = {
1797         0xfffe0101,                                     /* vs_1_1           */
1798         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1799         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1800         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1801         0x0000ffff                                      /* end              */
1802     };
1803     static const D3DVERTEXELEMENT9 decl_elements[] = {
1804         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1805         D3DDECL_END()
1806     };
1807     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1808      * then call Present. Then clear the color buffer to make sure it has some defined content
1809      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1810      * by the depth value.
1811      */
1812     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1813     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1814     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1815     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1816
1817     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1818     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1819     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1820     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1821     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1822     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1823     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1824     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1825     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1826     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1827
1828     hr = IDirect3DDevice9_BeginScene(device);
1829     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1830     if(hr == D3D_OK)
1831     {
1832         /* Test the untransformed vertex path */
1833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1834         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1835         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1836         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1837         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1838         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1839
1840         /* Test the transformed vertex path */
1841         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1842         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1843
1844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1845         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1846         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1847         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1848         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1849         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1850
1851         hr = IDirect3DDevice9_EndScene(device);
1852         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1853     }
1854
1855     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1856     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1857
1858     /* Do not test the exact corner pixels, but go pretty close to them */
1859
1860     /* Clipped because z > 1.0 */
1861     color = getPixelColor(device, 28, 238);
1862     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1863     color = getPixelColor(device, 28, 241);
1864     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1865
1866     /* Not clipped, > z buffer clear value(0.75) */
1867     color = getPixelColor(device, 31, 238);
1868     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1869     color = getPixelColor(device, 31, 241);
1870     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1871     color = getPixelColor(device, 100, 238);
1872     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1873     color = getPixelColor(device, 100, 241);
1874     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1875
1876     /* Not clipped, < z buffer clear value */
1877     color = getPixelColor(device, 104, 238);
1878     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1879     color = getPixelColor(device, 104, 241);
1880     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1881     color = getPixelColor(device, 318, 238);
1882     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1883     color = getPixelColor(device, 318, 241);
1884     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1885
1886     /* Clipped because z < 0.0 */
1887     color = getPixelColor(device, 321, 238);
1888     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1889     color = getPixelColor(device, 321, 241);
1890     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1891
1892     /* Test the shader path */
1893     IDirect3DDevice9_GetDeviceCaps(device, &caps);
1894     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1895         skip("Vertex shaders not supported\n");
1896         goto out;
1897     }
1898     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1899     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1900     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1901     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1902
1903     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1904
1905     IDirect3DDevice9_SetVertexDeclaration(device, decl);
1906     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1907     IDirect3DDevice9_SetVertexShader(device, shader);
1908     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1909
1910     hr = IDirect3DDevice9_BeginScene(device);
1911     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1912     if(hr == D3D_OK)
1913     {
1914         float colorf[] = {1.0, 0.0, 0.0, 1.0};
1915         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1916         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1917         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1918         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1919         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1920         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1921         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1922         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1923         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1924
1925         hr = IDirect3DDevice9_EndScene(device);
1926         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1927     }
1928
1929     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1930     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1931     IDirect3DDevice9_SetVertexShader(device, NULL);
1932     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1933
1934     IDirect3DVertexDeclaration9_Release(decl);
1935     IDirect3DVertexShader9_Release(shader);
1936
1937     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1938     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1939     /* Z < 1.0 */
1940     color = getPixelColor(device, 28, 238);
1941     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1942
1943     /* 1.0 < z < 0.75 */
1944     color = getPixelColor(device, 31, 238);
1945     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1946     color = getPixelColor(device, 100, 238);
1947     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1948
1949     /* 0.75 < z < 0.0 */
1950     color = getPixelColor(device, 104, 238);
1951     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1952     color = getPixelColor(device, 318, 238);
1953     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1954
1955     /* 0.0 < z */
1956     color = getPixelColor(device, 321, 238);
1957     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1958
1959     out:
1960     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
1961     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1962     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1963     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1964     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1965     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1966 }
1967
1968 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
1969 {
1970     D3DSURFACE_DESC desc;
1971     D3DLOCKED_RECT l;
1972     HRESULT hr;
1973     unsigned int x, y;
1974     DWORD *mem;
1975
1976     memset(&desc, 0, sizeof(desc));
1977     memset(&l, 0, sizeof(l));
1978     hr = IDirect3DSurface9_GetDesc(surface, &desc);
1979     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
1980     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
1981     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
1982     if(FAILED(hr)) return;
1983
1984     for(y = 0; y < desc.Height; y++)
1985     {
1986         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
1987         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
1988         {
1989             mem[x] = color;
1990         }
1991     }
1992     hr = IDirect3DSurface9_UnlockRect(surface);
1993     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
1994 }
1995
1996 static void maxmip_test(IDirect3DDevice9 *device)
1997 {
1998     IDirect3DTexture9 *texture = NULL;
1999     IDirect3DSurface9 *surface = NULL;
2000     HRESULT hr;
2001     DWORD color;
2002     const float quads[] = {
2003         -1.0,   -1.0,   0.0,    0.0,    0.0,
2004         -1.0,    0.0,   0.0,    0.0,    1.0,
2005          0.0,   -1.0,   0.0,    1.0,    0.0,
2006          0.0,    0.0,   0.0,    1.0,    1.0,
2007
2008          0.0,   -1.0,   0.0,    0.0,    0.0,
2009          0.0,    0.0,   0.0,    0.0,    1.0,
2010          1.0,   -1.0,   0.0,    1.0,    0.0,
2011          1.0,    0.0,   0.0,    1.0,    1.0,
2012
2013          0.0,    0.0,   0.0,    0.0,    0.0,
2014          0.0,    1.0,   0.0,    0.0,    1.0,
2015          1.0,    0.0,   0.0,    1.0,    0.0,
2016          1.0,    1.0,   0.0,    1.0,    1.0,
2017
2018         -1.0,    0.0,   0.0,    0.0,    0.0,
2019         -1.0,    1.0,   0.0,    0.0,    1.0,
2020          0.0,    0.0,   0.0,    1.0,    0.0,
2021          0.0,    1.0,   0.0,    1.0,    1.0,
2022     };
2023
2024     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2025     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2026
2027     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2028                                         &texture, NULL);
2029     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2030     if(!texture)
2031     {
2032         skip("Failed to create test texture\n");
2033         return;
2034     }
2035
2036     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2037     fill_surface(surface, 0xffff0000);
2038     IDirect3DSurface9_Release(surface);
2039     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2040     fill_surface(surface, 0xff00ff00);
2041     IDirect3DSurface9_Release(surface);
2042     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2043     fill_surface(surface, 0xff0000ff);
2044     IDirect3DSurface9_Release(surface);
2045
2046     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2048     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2049     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2050
2051     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2052     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2053
2054     hr = IDirect3DDevice9_BeginScene(device);
2055     if(SUCCEEDED(hr))
2056     {
2057         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2058         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2059         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2060         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2061
2062         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2063         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2064         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2065         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2066
2067         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2068         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2069         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2070         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2071
2072         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2073         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2074         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2075         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2076         hr = IDirect3DDevice9_EndScene(device);
2077     }
2078
2079     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2080     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2081     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2082     color = getPixelColor(device, 160, 360);
2083     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2084     color = getPixelColor(device, 160, 120);
2085     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2086     color = getPixelColor(device, 480, 120);
2087     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2088     color = getPixelColor(device, 480, 360);
2089     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2090
2091     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2092     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2093
2094     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2095     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2096
2097     hr = IDirect3DDevice9_BeginScene(device);
2098     if(SUCCEEDED(hr))
2099     {
2100         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2101         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2102         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2103         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2104
2105         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2106         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2107         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2108         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2109
2110         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2111         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2112         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2113         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2114
2115         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2116         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2117         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2118         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2119         hr = IDirect3DDevice9_EndScene(device);
2120     }
2121
2122     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2123     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2124     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2126
2127     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2128     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2129     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2130      * samples from the highest level in the texture(level 2)
2131      */
2132     color = getPixelColor(device, 160, 360);
2133     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2134     color = getPixelColor(device, 160, 120);
2135     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2136     color = getPixelColor(device, 480, 120);
2137     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2138     color = getPixelColor(device, 480, 360);
2139     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2140
2141     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2142     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2143     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2144     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2145     IDirect3DTexture9_Release(texture);
2146 }
2147
2148 static void release_buffer_test(IDirect3DDevice9 *device)
2149 {
2150     IDirect3DVertexBuffer9 *vb = NULL;
2151     IDirect3DIndexBuffer9 *ib = NULL;
2152     HRESULT hr;
2153     BYTE *data;
2154     long ref;
2155
2156     static const struct vertex quad[] = {
2157         {-1.0,      -1.0,       0.1,        0xffff0000},
2158         {-1.0,       1.0,       0.1,        0xffff0000},
2159         { 1.0,       1.0,       0.1,        0xffff0000},
2160
2161         {-1.0,      -1.0,       0.1,        0xff00ff00},
2162         {-1.0,       1.0,       0.1,        0xff00ff00},
2163         { 1.0,       1.0,       0.1,        0xff00ff00}
2164     };
2165     short indices[] = {3, 4, 5};
2166
2167     /* Index and vertex buffers should always be creatable */
2168     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2169                                               D3DPOOL_MANAGED, &vb, NULL);
2170     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2171     if(!vb) {
2172         skip("Failed to create a vertex buffer\n");
2173         return;
2174     }
2175     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2176     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2177     if(!ib) {
2178         skip("Failed to create an index buffer\n");
2179         return;
2180     }
2181
2182     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2183     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2184     memcpy(data, quad, sizeof(quad));
2185     hr = IDirect3DVertexBuffer9_Unlock(vb);
2186     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2187
2188     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2189     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2190     memcpy(data, indices, sizeof(indices));
2191     hr = IDirect3DIndexBuffer9_Unlock(ib);
2192     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2193
2194     hr = IDirect3DDevice9_SetIndices(device, ib);
2195     ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2196     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2197     ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2198     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2199     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2200
2201     /* Now destroy the bound index buffer and draw again */
2202     ref = IDirect3DIndexBuffer9_Release(ib);
2203     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2204
2205     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2207
2208     hr = IDirect3DDevice9_BeginScene(device);
2209     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2210     if(SUCCEEDED(hr))
2211     {
2212         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2213          * making assumptions about the indices or vertices
2214          */
2215         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2216         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2217         hr = IDirect3DDevice9_EndScene(device);
2218         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2219     }
2220
2221     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2222     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2223
2224     hr = IDirect3DDevice9_SetIndices(device, NULL);
2225     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2226     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2227     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2228
2229     /* Index buffer was already destroyed as part of the test */
2230     IDirect3DVertexBuffer9_Release(vb);
2231 }
2232
2233 static void float_texture_test(IDirect3DDevice9 *device)
2234 {
2235     IDirect3D9 *d3d = NULL;
2236     HRESULT hr;
2237     IDirect3DTexture9 *texture = NULL;
2238     D3DLOCKED_RECT lr;
2239     float *data;
2240     DWORD color;
2241     float quad[] = {
2242         -1.0,      -1.0,       0.1,     0.0,    0.0,
2243         -1.0,       1.0,       0.1,     0.0,    1.0,
2244          1.0,      -1.0,       0.1,     1.0,    0.0,
2245          1.0,       1.0,       0.1,     1.0,    1.0,
2246     };
2247
2248     memset(&lr, 0, sizeof(lr));
2249     IDirect3DDevice9_GetDirect3D(device, &d3d);
2250     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2251                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2252         skip("D3DFMT_R32F textures not supported\n");
2253         goto out;
2254     }
2255
2256     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2257                                         D3DPOOL_MANAGED, &texture, NULL);
2258     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2259     if(!texture) {
2260         skip("Failed to create R32F texture\n");
2261         goto out;
2262     }
2263
2264     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2265     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2266     data = lr.pBits;
2267     *data = 0.0;
2268     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2269     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2270
2271     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2272     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2273
2274     hr = IDirect3DDevice9_BeginScene(device);
2275     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2276     if(SUCCEEDED(hr))
2277     {
2278         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2279         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2280
2281         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2282         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2283
2284         hr = IDirect3DDevice9_EndScene(device);
2285         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2286     }
2287     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2288     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2289
2290     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2291     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2292
2293     color = getPixelColor(device, 240, 320);
2294     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2295
2296 out:
2297     if(texture) IDirect3DTexture9_Release(texture);
2298     IDirect3D9_Release(d3d);
2299 }
2300
2301 static void g16r16_texture_test(IDirect3DDevice9 *device)
2302 {
2303     IDirect3D9 *d3d = NULL;
2304     HRESULT hr;
2305     IDirect3DTexture9 *texture = NULL;
2306     D3DLOCKED_RECT lr;
2307     DWORD *data;
2308     DWORD color, red, green, blue;
2309     float quad[] = {
2310        -1.0,      -1.0,       0.1,     0.0,    0.0,
2311        -1.0,       1.0,       0.1,     0.0,    1.0,
2312         1.0,      -1.0,       0.1,     1.0,    0.0,
2313         1.0,       1.0,       0.1,     1.0,    1.0,
2314     };
2315
2316     memset(&lr, 0, sizeof(lr));
2317     IDirect3DDevice9_GetDirect3D(device, &d3d);
2318     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2319        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2320            skip("D3DFMT_G16R16 textures not supported\n");
2321            goto out;
2322     }
2323
2324     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2325                                         D3DPOOL_MANAGED, &texture, NULL);
2326     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2327     if(!texture) {
2328         skip("Failed to create D3DFMT_G16R16 texture\n");
2329         goto out;
2330     }
2331
2332     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2333     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2334     data = lr.pBits;
2335     *data = 0x0f00f000;
2336     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2337     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2338
2339     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2340     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2341
2342     hr = IDirect3DDevice9_BeginScene(device);
2343     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2344     if(SUCCEEDED(hr))
2345     {
2346         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2347         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2348
2349         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2350         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2351
2352         hr = IDirect3DDevice9_EndScene(device);
2353         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2354     }
2355     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2356     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2357
2358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2359     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2360
2361     color = getPixelColor(device, 240, 320);
2362     red   = (color & 0x00ff0000) >> 16;
2363     green = (color & 0x0000ff00) >>  8;
2364     blue  = (color & 0x000000ff) >>  0;
2365     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2366        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2367
2368 out:
2369     if(texture) IDirect3DTexture9_Release(texture);
2370     IDirect3D9_Release(d3d);
2371 }
2372
2373 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2374 {
2375     HRESULT hr;
2376     IDirect3D9 *d3d;
2377     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2378     D3DCAPS9 caps;
2379     IDirect3DTexture9 *texture = NULL;
2380     IDirect3DVolumeTexture9 *volume = NULL;
2381     unsigned int x, y, z;
2382     D3DLOCKED_RECT lr;
2383     D3DLOCKED_BOX lb;
2384     DWORD color;
2385     IDirect3DVertexDeclaration9 *decl, *decl2;
2386     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2387                            0.0, 1.0, 0.0, 0.0,
2388                            0.0, 0.0, 1.0, 0.0,
2389                            0.0, 0.0, 0.0, 1.0};
2390     static const D3DVERTEXELEMENT9 decl_elements[] = {
2391         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2392         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2393         D3DDECL_END()
2394     };
2395     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2396         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2397         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2398         D3DDECL_END()
2399     };
2400
2401     memset(&lr, 0, sizeof(lr));
2402     memset(&lb, 0, sizeof(lb));
2403     IDirect3DDevice9_GetDirect3D(device, &d3d);
2404     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2405                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2406         fmt = D3DFMT_A16B16G16R16;
2407     }
2408     IDirect3D9_Release(d3d);
2409
2410     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2411     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2412     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
2413     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2414     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
2415     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
2416     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2417     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
2418     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2419     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
2420     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2421     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
2422     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2423     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
2424     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2425     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
2426     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
2427     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
2428     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2429     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
2430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2432
2433     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2434     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
2435     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
2436                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
2437     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
2438     if(!texture) {
2439         skip("Failed to create the test texture\n");
2440         return;
2441     }
2442
2443     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
2444      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
2445      * 1.0 in red and green for the x and y coords
2446      */
2447     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2448     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
2449     for(y = 0; y < caps.MaxTextureHeight; y++) {
2450         for(x = 0; x < caps.MaxTextureWidth; x++) {
2451             double r_f = (double) y / (double) caps.MaxTextureHeight;
2452             double g_f = (double) x / (double) caps.MaxTextureWidth;
2453             if(fmt == D3DFMT_A16B16G16R16) {
2454                 unsigned short r, g;
2455                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
2456                 r = (unsigned short) (r_f * 65536.0);
2457                 g = (unsigned short) (g_f * 65536.0);
2458                 dst[0] = r;
2459                 dst[1] = g;
2460                 dst[2] = 0;
2461                 dst[3] = 65535;
2462             } else {
2463                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
2464                 unsigned char r = (unsigned char) (r_f * 255.0);
2465                 unsigned char g = (unsigned char) (g_f * 255.0);
2466                 dst[0] = 0;
2467                 dst[1] = g;
2468                 dst[2] = r;
2469                 dst[3] = 255;
2470             }
2471         }
2472     }
2473     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2474     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
2475     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2476     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2477
2478     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2479     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2480     hr = IDirect3DDevice9_BeginScene(device);
2481     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2482     if(SUCCEEDED(hr))
2483     {
2484         float quad1[] = {
2485             -1.0,      -1.0,       0.1,     1.0,    1.0,
2486             -1.0,       0.0,       0.1,     1.0,    1.0,
2487              0.0,      -1.0,       0.1,     1.0,    1.0,
2488              0.0,       0.0,       0.1,     1.0,    1.0,
2489         };
2490         float quad2[] = {
2491             -1.0,       0.0,       0.1,     1.0,    1.0,
2492             -1.0,       1.0,       0.1,     1.0,    1.0,
2493              0.0,       0.0,       0.1,     1.0,    1.0,
2494              0.0,       1.0,       0.1,     1.0,    1.0,
2495         };
2496         float quad3[] = {
2497              0.0,       0.0,       0.1,     0.5,    0.5,
2498              0.0,       1.0,       0.1,     0.5,    0.5,
2499              1.0,       0.0,       0.1,     0.5,    0.5,
2500              1.0,       1.0,       0.1,     0.5,    0.5,
2501         };
2502         float quad4[] = {
2503              320,       480,       0.1,     1.0,    0.0,    1.0,
2504              320,       240,       0.1,     1.0,    0.0,    1.0,
2505              640,       480,       0.1,     1.0,    0.0,    1.0,
2506              640,       240,       0.1,     1.0,    0.0,    1.0,
2507         };
2508         float mat[16] = {0.0, 0.0, 0.0, 0.0,
2509                           0.0, 0.0, 0.0, 0.0,
2510                           0.0, 0.0, 0.0, 0.0,
2511                           0.0, 0.0, 0.0, 0.0};
2512
2513         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
2514         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2515         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2516         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2517         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2518
2519         /* What happens with transforms enabled? */
2520         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2521         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2522         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2523         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2524
2525         /* What happens if 4 coords are used, but only 2 given ?*/
2526         mat[8] = 1.0;
2527         mat[13] = 1.0;
2528         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2529         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2530         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2531         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2532         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2533         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2534
2535         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
2536          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
2537          * due to the coords in the vertices. (turns out red, indeed)
2538          */
2539         memset(mat, 0, sizeof(mat));
2540         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2541         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2542         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
2543         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2544         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2545         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2546         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2547         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2548
2549         hr = IDirect3DDevice9_EndScene(device);
2550         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2551     }
2552     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2553     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2554     color = getPixelColor(device, 160, 360);
2555     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
2556     color = getPixelColor(device, 160, 120);
2557     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2558     color = getPixelColor(device, 480, 120);
2559     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
2560     color = getPixelColor(device, 480, 360);
2561     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
2562
2563     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2564     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2565
2566     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2567     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2568     hr = IDirect3DDevice9_BeginScene(device);
2569     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2570     if(SUCCEEDED(hr))
2571     {
2572         float quad1[] = {
2573             -1.0,      -1.0,       0.1,     0.8,    0.2,
2574             -1.0,       0.0,       0.1,     0.8,    0.2,
2575              0.0,      -1.0,       0.1,     0.8,    0.2,
2576              0.0,       0.0,       0.1,     0.8,    0.2,
2577         };
2578         float quad2[] = {
2579             -1.0,       0.0,       0.1,     0.5,    1.0,
2580             -1.0,       1.0,       0.1,     0.5,    1.0,
2581              0.0,       0.0,       0.1,     0.5,    1.0,
2582              0.0,       1.0,       0.1,     0.5,    1.0,
2583         };
2584         float quad3[] = {
2585              0.0,       0.0,       0.1,     0.5,    1.0,
2586              0.0,       1.0,       0.1,     0.5,    1.0,
2587              1.0,       0.0,       0.1,     0.5,    1.0,
2588              1.0,       1.0,       0.1,     0.5,    1.0,
2589         };
2590         float quad4[] = {
2591              0.0,      -1.0,       0.1,     0.8,    0.2,
2592              0.0,       0.0,       0.1,     0.8,    0.2,
2593              1.0,      -1.0,       0.1,     0.8,    0.2,
2594              1.0,       0.0,       0.1,     0.8,    0.2,
2595         };
2596         float mat[16] = {0.0, 0.0, 0.0, 0.0,
2597                           0.0, 0.0, 0.0, 0.0,
2598                           0.0, 1.0, 0.0, 0.0,
2599                           0.0, 0.0, 0.0, 0.0};
2600
2601         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
2602          */
2603         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2604         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2605         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2606         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2607
2608         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2609         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2610
2611         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
2612          * it behaves like COUNT2 because normal textures require 2 coords
2613          */
2614         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2615         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2616         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
2617         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2618
2619         /* Just to be sure, the same as quad2 above */
2620         memset(mat, 0, sizeof(mat));
2621         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2622         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2623         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2624         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2625         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2626         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2627
2628         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
2629          * used? And what happens to the first?
2630          */
2631         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2632         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2633         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2634         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2635
2636         hr = IDirect3DDevice9_EndScene(device);
2637         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2638     }
2639     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2640     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2641     color = getPixelColor(device, 160, 360);
2642     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
2643     color = getPixelColor(device, 160, 120);
2644     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2645     color = getPixelColor(device, 480, 120);
2646     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
2647        "quad 3 has color %08x, expected 0x00ff8000\n", color);
2648     color = getPixelColor(device, 480, 360);
2649     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
2650        "quad 4 has color %08x, expected 0x0033cc00\n", color);
2651
2652     IDirect3DTexture9_Release(texture);
2653
2654     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
2655     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2656     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
2657      * Thus watch out if sampling from texels between 0 and 1.
2658      */
2659     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
2660     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
2661        "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
2662     if(!volume) {
2663         skip("Failed to create a volume texture\n");
2664         goto out;
2665     }
2666
2667     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
2668     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
2669     for(z = 0; z < 32; z++) {
2670         for(y = 0; y < 32; y++) {
2671             for(x = 0; x < 32; x++) {
2672                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
2673                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
2674                 float r_f = (float) x / 31.0;
2675                 float g_f = (float) y / 31.0;
2676                 float b_f = (float) z / 31.0;
2677
2678                 if(fmt == D3DFMT_A16B16G16R16) {
2679                     unsigned short *mem_s = mem;
2680                     mem_s[0]  = r_f * 65535.0;
2681                     mem_s[1]  = g_f * 65535.0;
2682                     mem_s[2]  = b_f * 65535.0;
2683                     mem_s[3]  = 65535;
2684                 } else {
2685                     unsigned char *mem_c = mem;
2686                     mem_c[0]  = b_f * 255.0;
2687                     mem_c[1]  = g_f * 255.0;
2688                     mem_c[2]  = r_f * 255.0;
2689                     mem_c[3]  = 255;
2690                 }
2691             }
2692         }
2693     }
2694     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
2695     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2696
2697     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
2698     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2699
2700     hr = IDirect3DDevice9_BeginScene(device);
2701     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2702     if(SUCCEEDED(hr))
2703     {
2704         float quad1[] = {
2705             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2706             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2707              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2708              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
2709         };
2710         float quad2[] = {
2711             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2712             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
2713              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2714              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
2715         };
2716         float quad3[] = {
2717              0.0,       0.0,       0.1,     0.0,    0.0,
2718              0.0,       1.0,       0.1,     0.0,    0.0,
2719              1.0,       0.0,       0.1,     0.0,    0.0,
2720              1.0,       1.0,       0.1,     0.0,    0.0
2721         };
2722         float quad4[] = {
2723              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2724              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2725              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2726              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
2727         };
2728         float mat[16] = {1.0, 0.0, 0.0, 0.0,
2729                          0.0, 0.0, 1.0, 0.0,
2730                          0.0, 1.0, 0.0, 0.0,
2731                          0.0, 0.0, 0.0, 1.0};
2732         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2733         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2734
2735         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
2736          * values
2737          */
2738         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2739         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2740         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2741         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2742         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2743         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2744
2745         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
2746          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
2747          * otherwise the w will be missing(blue).
2748          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
2749          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
2750          */
2751         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2752         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2753         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2754         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2755
2756         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
2757         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2758         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2759         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2760         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2761         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2762         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2763         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2764         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2765
2766         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
2767          * disable. ATI extends it up to the amount of values needed for the volume texture
2768          */
2769         memset(mat, 0, sizeof(mat));
2770         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2771         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2772         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2773         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2774         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2775         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2777         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2778
2779         hr = IDirect3DDevice9_EndScene(device);
2780         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2781     }
2782     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2783     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2784
2785     color = getPixelColor(device, 160, 360);
2786     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
2787     color = getPixelColor(device, 160, 120);
2788     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
2789        "quad 2 has color %08x, expected 0x00ffff00\n", color);
2790     color = getPixelColor(device, 480, 120);
2791     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
2792     color = getPixelColor(device, 480, 360);
2793     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
2794
2795     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
2796     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2797     hr = IDirect3DDevice9_BeginScene(device);
2798     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2799     if(SUCCEEDED(hr))
2800     {
2801         float quad1[] = {
2802             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2803             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2804              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2805              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
2806         };
2807         float quad2[] = {
2808             -1.0,       0.0,       0.1,
2809             -1.0,       1.0,       0.1,
2810              0.0,       0.0,       0.1,
2811              0.0,       1.0,       0.1,
2812         };
2813         float quad3[] = {
2814              0.0,       0.0,       0.1,     1.0,
2815              0.0,       1.0,       0.1,     1.0,
2816              1.0,       0.0,       0.1,     1.0,
2817              1.0,       1.0,       0.1,     1.0
2818         };
2819         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
2820                            0.0, 0.0, 0.0, 0.0,
2821                            0.0, 0.0, 0.0, 0.0,
2822                            0.0, 1.0, 0.0, 0.0};
2823         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
2824                            1.0, 0.0, 0.0, 0.0,
2825                            0.0, 1.0, 0.0, 0.0,
2826                            0.0, 0.0, 1.0, 0.0};
2827         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2828         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2829
2830         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
2831          */
2832         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2833         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2834         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2835         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2836         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2837         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2838
2839         /* None passed */
2840         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2841         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2842         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2843         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
2845         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2846
2847         /* 4 used, 1 passed */
2848         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
2849         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2850         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
2851         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2852         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
2853         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2854
2855         hr = IDirect3DDevice9_EndScene(device);
2856         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2857     }
2858     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2859     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2860     color = getPixelColor(device, 160, 360);
2861     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
2862     color = getPixelColor(device, 160, 120);
2863     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
2864     color = getPixelColor(device, 480, 120);
2865     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
2866     /* Quad4: unused */
2867
2868     IDirect3DVolumeTexture9_Release(volume);
2869
2870     out:
2871     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2872     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2873     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2874     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2875     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
2876     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2877     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2878     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2879     IDirect3DVertexDeclaration9_Release(decl);
2880     IDirect3DVertexDeclaration9_Release(decl2);
2881 }
2882
2883 static void texdepth_test(IDirect3DDevice9 *device)
2884 {
2885     IDirect3DPixelShader9 *shader;
2886     HRESULT hr;
2887     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
2888     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
2889     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
2890     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
2891     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
2892     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
2893     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
2894     DWORD shader_code[] = {
2895         0xffff0104,                                                                 /* ps_1_4               */
2896         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
2897         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
2898         0x0000fffd,                                                                 /* phase                */
2899         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
2900         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
2901         0x0000ffff                                                                  /* end                  */
2902     };
2903     DWORD color;
2904     float vertex[] = {
2905        -1.0,   -1.0,    0.0,
2906         1.0,   -1.0,    1.0,
2907        -1.0,    1.0,    0.0,
2908         1.0,    1.0,    1.0
2909     };
2910
2911     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
2912     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2913
2914     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
2915     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2916     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2917     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2918     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2919     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2921     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2922     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2923
2924     /* Fill the depth buffer with a gradient */
2925     hr = IDirect3DDevice9_BeginScene(device);
2926     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2927     if(SUCCEEDED(hr))
2928     {
2929         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2930         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2931         hr = IDirect3DDevice9_EndScene(device);
2932         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2933     }
2934
2935     /* Now perform the actual tests. Same geometry, but with the shader */
2936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2937     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2938     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2939     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2940     hr = IDirect3DDevice9_SetPixelShader(device, shader);
2941     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2942
2943     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
2944     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2945     hr = IDirect3DDevice9_BeginScene(device);
2946     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2947     if(SUCCEEDED(hr))
2948     {
2949         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2950         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2951
2952         hr = IDirect3DDevice9_EndScene(device);
2953         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2954     }
2955
2956     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2957     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2958     color = getPixelColor(device, 158, 240);
2959     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2960     color = getPixelColor(device, 162, 240);
2961     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
2962
2963     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2964
2965     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
2966     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2967     hr = IDirect3DDevice9_BeginScene(device);
2968     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2969     if(SUCCEEDED(hr))
2970     {
2971         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2972         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2973
2974         hr = IDirect3DDevice9_EndScene(device);
2975         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2976     }
2977
2978     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2979     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2980     color = getPixelColor(device, 318, 240);
2981     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2982     color = getPixelColor(device, 322, 240);
2983     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
2984
2985     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2986
2987     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
2988     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2989     hr = IDirect3DDevice9_BeginScene(device);
2990     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2991     if(SUCCEEDED(hr))
2992     {
2993         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2994         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2995
2996         hr = IDirect3DDevice9_EndScene(device);
2997         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2998     }
2999     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3000     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3001
3002     color = getPixelColor(device, 1, 240);
3003     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3004
3005     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3006
3007     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3008     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3009     hr = IDirect3DDevice9_BeginScene(device);
3010     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3011     if(SUCCEEDED(hr))
3012     {
3013         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3014         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3015
3016         hr = IDirect3DDevice9_EndScene(device);
3017         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3018     }
3019     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3020     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3021     color = getPixelColor(device, 318, 240);
3022     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3023     color = getPixelColor(device, 322, 240);
3024     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3025
3026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3027
3028     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3029     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3030     hr = IDirect3DDevice9_BeginScene(device);
3031     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3032     if(SUCCEEDED(hr))
3033     {
3034         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3035         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3036
3037         hr = IDirect3DDevice9_EndScene(device);
3038         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3039     }
3040     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3041     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3042
3043     color = getPixelColor(device, 1, 240);
3044     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3045
3046     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3047
3048     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3049     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3050     hr = IDirect3DDevice9_BeginScene(device);
3051     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3052     if(SUCCEEDED(hr))
3053     {
3054         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3055         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3056
3057         hr = IDirect3DDevice9_EndScene(device);
3058         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3059     }
3060     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3061     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3062
3063     color = getPixelColor(device, 638, 240);
3064     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3065
3066     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3067
3068     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3069     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3070     hr = IDirect3DDevice9_BeginScene(device);
3071     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3072     if(SUCCEEDED(hr))
3073     {
3074         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3075         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3076
3077         hr = IDirect3DDevice9_EndScene(device);
3078         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3079     }
3080     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3081     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3082
3083     color = getPixelColor(device, 638, 240);
3084     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3085
3086     /* Cleanup */
3087     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3088     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3089     IDirect3DPixelShader9_Release(shader);
3090
3091     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3092     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3093     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3094     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3095 }
3096
3097 static void texkill_test(IDirect3DDevice9 *device)
3098 {
3099     IDirect3DPixelShader9 *shader;
3100     HRESULT hr;
3101     DWORD color;
3102
3103     const float vertex[] = {
3104     /*                          bottom  top    right    left */
3105         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3106          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3107         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3108          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3109     };
3110
3111     DWORD shader_code_11[] = {
3112     0xffff0101,                                                             /* ps_1_1                     */
3113     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3114     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3115     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3116     0x0000ffff                                                              /* end                        */
3117     };
3118     DWORD shader_code_20[] = {
3119     0xffff0200,                                                             /* ps_2_0                     */
3120     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3121     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3122     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3123     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3124     0x0000ffff                                                              /* end                        */
3125     };
3126
3127     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3128     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3129     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3130     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3131
3132     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3133     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3134     hr = IDirect3DDevice9_BeginScene(device);
3135     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3136     if(SUCCEEDED(hr))
3137     {
3138         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3139         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3141         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3142         hr = IDirect3DDevice9_EndScene(device);
3143         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3144     }
3145     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3146     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3147     color = getPixelColor(device, 63, 46);
3148     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3149     color = getPixelColor(device, 66, 46);
3150     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3151     color = getPixelColor(device, 63, 49);
3152     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3153     color = getPixelColor(device, 66, 49);
3154     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3155
3156     color = getPixelColor(device, 578, 46);
3157     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3158     color = getPixelColor(device, 575, 46);
3159     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3160     color = getPixelColor(device, 578, 49);
3161     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3162     color = getPixelColor(device, 575, 49);
3163     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3164
3165     color = getPixelColor(device, 63, 430);
3166     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3167     color = getPixelColor(device, 63, 433);
3168     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3169     color = getPixelColor(device, 66, 433);
3170     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3171     color = getPixelColor(device, 66, 430);
3172     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3173
3174     color = getPixelColor(device, 578, 430);
3175     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3176     color = getPixelColor(device, 578, 433);
3177     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3178     color = getPixelColor(device, 575, 433);
3179     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3180     color = getPixelColor(device, 575, 430);
3181     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3182
3183     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3184     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3185     IDirect3DPixelShader9_Release(shader);
3186
3187     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3188     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3189     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3190     if(FAILED(hr)) {
3191         skip("Failed to create 2.0 test shader, most likely not supported\n");
3192         return;
3193     }
3194
3195     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3196     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3197     hr = IDirect3DDevice9_BeginScene(device);
3198     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3199     if(SUCCEEDED(hr))
3200     {
3201         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3202         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3203         hr = IDirect3DDevice9_EndScene(device);
3204         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3205     }
3206     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3207
3208     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3209     color = getPixelColor(device, 63, 46);
3210     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3211     color = getPixelColor(device, 66, 46);
3212     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3213     color = getPixelColor(device, 63, 49);
3214     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3215     color = getPixelColor(device, 66, 49);
3216     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3217
3218     color = getPixelColor(device, 578, 46);
3219     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3220     color = getPixelColor(device, 575, 46);
3221     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3222     color = getPixelColor(device, 578, 49);
3223     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3224     color = getPixelColor(device, 575, 49);
3225     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3226
3227     color = getPixelColor(device, 63, 430);
3228     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3229     color = getPixelColor(device, 63, 433);
3230     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3231     color = getPixelColor(device, 66, 433);
3232     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3233     color = getPixelColor(device, 66, 430);
3234     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3235
3236     color = getPixelColor(device, 578, 430);
3237     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3238     color = getPixelColor(device, 578, 433);
3239     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3240     color = getPixelColor(device, 575, 433);
3241     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3242     color = getPixelColor(device, 575, 430);
3243     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3244
3245     /* Cleanup */
3246     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3247     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3248     IDirect3DPixelShader9_Release(shader);
3249 }
3250
3251 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3252 {
3253     IDirect3D9 *d3d9;
3254     HRESULT hr;
3255     IDirect3DTexture9 *texture;
3256     IDirect3DPixelShader9 *shader;
3257     IDirect3DPixelShader9 *shader2;
3258     D3DLOCKED_RECT lr;
3259     DWORD color;
3260     DWORD shader_code[] = {
3261         0xffff0101,                             /* ps_1_1       */
3262         0x00000042, 0xb00f0000,                 /* tex t0       */
3263         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3264         0x0000ffff                              /* end          */
3265     };
3266     DWORD shader_code2[] = {
3267         0xffff0101,                             /* ps_1_1       */
3268         0x00000042, 0xb00f0000,                 /* tex t0       */
3269         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3270         0x0000ffff                              /* end          */
3271     };
3272
3273     float quad[] = {
3274        -1.0,   -1.0,   0.1,     0.5,    0.5,
3275         1.0,   -1.0,   0.1,     0.5,    0.5,
3276        -1.0,    1.0,   0.1,     0.5,    0.5,
3277         1.0,    1.0,   0.1,     0.5,    0.5,
3278     };
3279
3280     memset(&lr, 0, sizeof(lr));
3281     IDirect3DDevice9_GetDirect3D(device, &d3d9);
3282     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3283                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
3284     IDirect3D9_Release(d3d9);
3285     if(FAILED(hr)) {
3286         skip("No D3DFMT_X8L8V8U8 support\n");
3287     };
3288
3289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3290     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3291
3292     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
3293     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
3294     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3295     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
3296     *((DWORD *) lr.pBits) = 0x11ca3141;
3297     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3298     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
3299
3300     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3302     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
3303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3304
3305     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3306     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
3307     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3308     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3309     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3310     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3311
3312     hr = IDirect3DDevice9_BeginScene(device);
3313     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3314     if(SUCCEEDED(hr))
3315     {
3316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3318
3319         hr = IDirect3DDevice9_EndScene(device);
3320         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3321     }
3322     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3323     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3324     color = getPixelColor(device, 578, 430);
3325     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
3326        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
3327
3328     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
3329     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3330     hr = IDirect3DDevice9_BeginScene(device);
3331     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3332     if(SUCCEEDED(hr))
3333     {
3334         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3335         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3336
3337         hr = IDirect3DDevice9_EndScene(device);
3338         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3339     }
3340     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3341     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3342     color = getPixelColor(device, 578, 430);
3343     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
3344
3345     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3346     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3347     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3348     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3349     IDirect3DPixelShader9_Release(shader);
3350     IDirect3DPixelShader9_Release(shader2);
3351     IDirect3DTexture9_Release(texture);
3352 }
3353
3354 static void autogen_mipmap_test(IDirect3DDevice9 *device)
3355 {
3356     HRESULT hr;
3357     IDirect3D9 *d3d;
3358     IDirect3DTexture9 *texture = NULL;
3359     IDirect3DSurface9 *surface;
3360     DWORD color;
3361     const RECT r1 = {256, 256, 512, 512};
3362     const RECT r2 = {512, 256, 768, 512};
3363     const RECT r3 = {256, 512, 512, 768};
3364     const RECT r4 = {512, 512, 768, 768};
3365     unsigned int x, y;
3366     D3DLOCKED_RECT lr;
3367     memset(&lr, 0, sizeof(lr));
3368
3369     IDirect3DDevice9_GetDirect3D(device, &d3d);
3370     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3371        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
3372         skip("No autogenmipmap support\n");
3373         IDirect3D9_Release(d3d);
3374         return;
3375     }
3376     IDirect3D9_Release(d3d);
3377
3378     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3379     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3380
3381     /* Make the mipmap big, so that a smaller mipmap is used
3382      */
3383     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
3384                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3386
3387     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3388     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
3389     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
3390     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
3391     for(y = 0; y < 1024; y++) {
3392         for(x = 0; x < 1024; x++) {
3393             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
3394             POINT pt;
3395
3396             pt.x = x;
3397             pt.y = y;
3398             if(PtInRect(&r1, pt)) {
3399                 *dst = 0xffff0000;
3400             } else if(PtInRect(&r2, pt)) {
3401                 *dst = 0xff00ff00;
3402             } else if(PtInRect(&r3, pt)) {
3403                 *dst = 0xff0000ff;
3404             } else if(PtInRect(&r4, pt)) {
3405                 *dst = 0xff000000;
3406             } else {
3407                 *dst = 0xffffffff;
3408             }
3409         }
3410     }
3411     hr = IDirect3DSurface9_UnlockRect(surface);
3412     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3413     IDirect3DSurface9_Release(surface);
3414
3415     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3416     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3417     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3418     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3419
3420     hr = IDirect3DDevice9_BeginScene(device);
3421     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3422     if(SUCCEEDED(hr)) {
3423         const float quad[] =  {
3424            -0.5,   -0.5,    0.1,    0.0,    0.0,
3425            -0.5,    0.5,    0.1,    0.0,    1.0,
3426             0.5,   -0.5,    0.1,    1.0,    0.0,
3427             0.5,    0.5,    0.1,    1.0,    1.0
3428         };
3429
3430         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3431         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3433         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3434         hr = IDirect3DDevice9_EndScene(device);
3435         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3436     }
3437     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3438     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3439     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3440     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3441     IDirect3DTexture9_Release(texture);
3442
3443     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3444     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3445     color = getPixelColor(device, 200, 200);
3446     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
3447     color = getPixelColor(device, 280, 200);
3448     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
3449     color = getPixelColor(device, 360, 200);
3450     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
3451     color = getPixelColor(device, 440, 200);
3452     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3453     color = getPixelColor(device, 200, 270);
3454     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
3455     color = getPixelColor(device, 280, 270);
3456     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
3457     color = getPixelColor(device, 360, 270);
3458     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
3459     color = getPixelColor(device, 440, 270);
3460     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3461 }
3462
3463 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
3464 {
3465     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
3466     IDirect3DVertexDeclaration9 *decl;
3467     HRESULT hr;
3468     DWORD color;
3469     DWORD shader_code_11[] =  {
3470         0xfffe0101,                                         /* vs_1_1           */
3471         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3472         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3473         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3474         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3475         0x0000ffff                                          /* end              */
3476     };
3477     DWORD shader_code_11_2[] =  {
3478         0xfffe0101,                                         /* vs_1_1           */
3479         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
3480         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
3481         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3482         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3483         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3484         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3485         0x0000ffff                                          /* end              */
3486     };
3487     DWORD shader_code_20[] =  {
3488         0xfffe0200,                                         /* vs_2_0           */
3489         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3490         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3491         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3492         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3493         0x0000ffff                                          /* end              */
3494     };
3495     DWORD shader_code_20_2[] =  {
3496         0xfffe0200,                                         /* vs_2_0           */
3497         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
3498         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
3499         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3500         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3501         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3502         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3503         0x0000ffff                                          /* end              */
3504     };
3505     static const D3DVERTEXELEMENT9 decl_elements[] = {
3506         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3507         D3DDECL_END()
3508     };
3509     float quad1[] = {
3510         -1.0,   -1.0,   0.1,
3511          0.0,   -1.0,   0.1,
3512         -1.0,    0.0,   0.1,
3513          0.0,    0.0,   0.1
3514     };
3515     float quad2[] = {
3516          0.0,   -1.0,   0.1,
3517          1.0,   -1.0,   0.1,
3518          0.0,    0.0,   0.1,
3519          1.0,    0.0,   0.1
3520     };
3521     float quad3[] = {
3522          0.0,    0.0,   0.1,
3523          1.0,    0.0,   0.1,
3524          0.0,    1.0,   0.1,
3525          1.0,    1.0,   0.1
3526     };
3527     float quad4[] = {
3528         -1.0,    0.0,   0.1,
3529          0.0,    0.0,   0.1,
3530         -1.0,    1.0,   0.1,
3531          0.0,    1.0,   0.1
3532     };
3533     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3534     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3535
3536     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3538
3539     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
3540     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3541     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
3542     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3543     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
3544     if(FAILED(hr)) shader_20 = NULL;
3545     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
3546     if(FAILED(hr)) shader_20_2 = NULL;
3547     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3548     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3549
3550     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
3551     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3552     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
3553     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3554     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3555     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3556
3557     hr = IDirect3DDevice9_BeginScene(device);
3558     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3559     if(SUCCEEDED(hr))
3560     {
3561         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
3562         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3564         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3565
3566         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
3567         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3568         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3569         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3570
3571         if(shader_20) {
3572             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
3573             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3574             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3575             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3576         }
3577
3578         if(shader_20_2) {
3579             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
3580             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3581             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3582             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3583         }
3584
3585         hr = IDirect3DDevice9_EndScene(device);
3586         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3587     }
3588     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3589     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3590
3591     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3592     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3593     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3594     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3595
3596     color = getPixelColor(device, 160, 360);
3597     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3598        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
3599     color = getPixelColor(device, 480, 360);
3600     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3601        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
3602     if(shader_20) {
3603         color = getPixelColor(device, 160, 120);
3604         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3605            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
3606     }
3607     if(shader_20_2) {
3608         color = getPixelColor(device, 480, 120);
3609         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3610            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3611     }
3612
3613     IDirect3DVertexDeclaration9_Release(decl);
3614     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
3615     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
3616     IDirect3DVertexShader9_Release(shader_11_2);
3617     IDirect3DVertexShader9_Release(shader_11);
3618 }
3619
3620 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
3621 {
3622     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
3623     HRESULT hr;
3624     DWORD color;
3625     DWORD shader_code_11[] =  {
3626         0xffff0101,                                         /* ps_1_1           */
3627         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3628         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3629         0x0000ffff                                          /* end              */
3630     };
3631     DWORD shader_code_12[] =  {
3632         0xffff0102,                                         /* ps_1_2           */
3633         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3634         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3635         0x0000ffff                                          /* end              */
3636     };
3637     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
3638      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
3639      * During development of this test, 1.3 shaders were verified too
3640      */
3641     DWORD shader_code_14[] =  {
3642         0xffff0104,                                         /* ps_1_4           */
3643         /* Try to make one constant local. It gets clamped too, although the binary contains
3644          * the bigger numbers
3645          */
3646         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
3647         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3648         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3649         0x0000ffff                                          /* end              */
3650     };
3651     DWORD shader_code_20[] =  {
3652         0xffff0200,                                         /* ps_2_0           */
3653         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3654         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3655         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
3656         0x0000ffff                                          /* end              */
3657     };
3658     float quad1[] = {
3659         -1.0,   -1.0,   0.1,
3660          0.0,   -1.0,   0.1,
3661         -1.0,    0.0,   0.1,
3662          0.0,    0.0,   0.1
3663     };
3664     float quad2[] = {
3665          0.0,   -1.0,   0.1,
3666          1.0,   -1.0,   0.1,
3667          0.0,    0.0,   0.1,
3668          1.0,    0.0,   0.1
3669     };
3670     float quad3[] = {
3671          0.0,    0.0,   0.1,
3672          1.0,    0.0,   0.1,
3673          0.0,    1.0,   0.1,
3674          1.0,    1.0,   0.1
3675     };
3676     float quad4[] = {
3677         -1.0,    0.0,   0.1,
3678          0.0,    0.0,   0.1,
3679         -1.0,    1.0,   0.1,
3680          0.0,    1.0,   0.1
3681     };
3682     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3683     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3684
3685     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3686     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3687
3688     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3689     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3690     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3691     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3692     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3693     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3694     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
3695     if(FAILED(hr)) shader_20 = NULL;
3696
3697     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3698     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3699     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3700     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3701     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3702     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3703
3704     hr = IDirect3DDevice9_BeginScene(device);
3705     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3706     if(SUCCEEDED(hr))
3707     {
3708         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3709         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3711         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3712
3713         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3714         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3715         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3716         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3717
3718         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3719         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3720         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3721         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3722
3723         if(shader_20) {
3724             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
3725             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3726             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3727             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3728         }
3729
3730         hr = IDirect3DDevice9_EndScene(device);
3731         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3732     }
3733     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3734     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3735
3736     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3737     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3738
3739     color = getPixelColor(device, 160, 360);
3740     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3741        "quad 1 has color %08x, expected 0x00808000\n", color);
3742     color = getPixelColor(device, 480, 360);
3743     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3744        "quad 2 has color %08x, expected 0x00808000\n", color);
3745     color = getPixelColor(device, 480, 120);
3746     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3747        "quad 3 has color %08x, expected 0x00808000\n", color);
3748     if(shader_20) {
3749         color = getPixelColor(device, 160, 120);
3750         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3751            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3752     }
3753
3754     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
3755     IDirect3DPixelShader9_Release(shader_14);
3756     IDirect3DPixelShader9_Release(shader_12);
3757     IDirect3DPixelShader9_Release(shader_11);
3758 }
3759
3760 static void cnd_test(IDirect3DDevice9 *device)
3761 {
3762     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
3763     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
3764     HRESULT hr;
3765     DWORD color;
3766     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
3767      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
3768      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
3769      */
3770     DWORD shader_code_11[] =  {
3771         0xffff0101,                                                                 /* ps_1_1               */
3772         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3773         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3774         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
3775         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3776         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3777         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3778         0x0000ffff                                                                  /* end                  */
3779     };
3780     DWORD shader_code_12[] =  {
3781         0xffff0102,                                                                 /* ps_1_2               */
3782         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3783         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3784         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3785         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3786         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3787         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3788         0x0000ffff                                                                  /* end                  */
3789     };
3790     DWORD shader_code_13[] =  {
3791         0xffff0103,                                                                 /* ps_1_3               */
3792         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3793         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3794         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3795         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
3796         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3797         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3798         0x0000ffff                                                                  /* end                  */
3799     };
3800     DWORD shader_code_14[] =  {
3801         0xffff0104,                                                                 /* ps_1_3               */
3802         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
3803         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
3804         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
3805         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
3806         0x0000ffff                                                                  /* end                  */
3807     };
3808
3809     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
3810      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
3811      * set by the compiler, it was added manually after compilation. It isn't always allowed,
3812      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
3813      * native CreatePixelShader returns an error.
3814      *
3815      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
3816      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
3817      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
3818      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
3819      */
3820     DWORD shader_code_11_coissue[] =  {
3821         0xffff0101,                                                             /* ps_1_1                   */
3822         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3823         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3824         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3825         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3826         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3827         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3828         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3829         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3830         /* 0x40000000 = D3DSI_COISSUE */
3831         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3832         0x0000ffff                                                              /* end                      */
3833     };
3834     DWORD shader_code_12_coissue[] =  {
3835         0xffff0102,                                                             /* ps_1_2                   */
3836         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3837         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3838         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3839         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3840         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3841         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3842         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3843         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3844         /* 0x40000000 = D3DSI_COISSUE */
3845         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3846         0x0000ffff                                                              /* end                      */
3847     };
3848     DWORD shader_code_13_coissue[] =  {
3849         0xffff0103,                                                             /* ps_1_3                   */
3850         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3851         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3852         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3853         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3854         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3855         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3856         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3857         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3858         /* 0x40000000 = D3DSI_COISSUE */
3859         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3860         0x0000ffff                                                              /* end                      */
3861     };
3862     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
3863      * compare against 0.5
3864      */
3865     DWORD shader_code_14_coissue[] =  {
3866         0xffff0104,                                                             /* ps_1_4                   */
3867         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
3868         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
3869         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
3870         /* 0x40000000 = D3DSI_COISSUE */
3871         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
3872         0x0000ffff                                                              /* end                      */
3873     };
3874     float quad1[] = {
3875         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
3876          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
3877         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
3878          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
3879     };
3880     float quad2[] = {
3881          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
3882          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
3883          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
3884          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
3885     };
3886     float quad3[] = {
3887          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
3888          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
3889          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
3890          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
3891     };
3892     float quad4[] = {
3893         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
3894          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
3895         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
3896          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
3897     };
3898     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
3899     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
3900     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
3901     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
3902
3903     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3904     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3905
3906     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3907     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3908     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3909     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3910     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
3911     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3912     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3913     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3914     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
3915     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3916     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
3917     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3918     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
3919     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3920     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
3921     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3922
3923     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3924     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3925     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3926     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3927     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3928     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3929
3930     hr = IDirect3DDevice9_BeginScene(device);
3931     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3932     if(SUCCEEDED(hr))
3933     {
3934         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3935         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3936         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3937         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3938
3939         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3940         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3941         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3942         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3943
3944         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
3945         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3946         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
3947         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3948
3949         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3950         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3951         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3952         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3953
3954         hr = IDirect3DDevice9_EndScene(device);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3956     }
3957     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3958     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3959
3960     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3961     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3962
3963     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
3964     color = getPixelColor(device, 158, 118);
3965     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
3966     color = getPixelColor(device, 162, 118);
3967     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
3968     color = getPixelColor(device, 158, 122);
3969     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
3970     color = getPixelColor(device, 162, 122);
3971     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
3972
3973     /* 1.1 shader. All 3 components get set, based on the .w comparison */
3974     color = getPixelColor(device, 158, 358);
3975     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
3976     color = getPixelColor(device, 162, 358);
3977     ok(color == 0x00000000, "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
3978     color = getPixelColor(device, 158, 362);
3979     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
3980     color = getPixelColor(device, 162, 362);
3981     ok(color == 0x00000000, "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
3982
3983     /* 1.2 shader */
3984     color = getPixelColor(device, 478, 358);
3985     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
3986     color = getPixelColor(device, 482, 358);
3987     ok(color == 0x00000000, "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
3988     color = getPixelColor(device, 478, 362);
3989     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
3990     color = getPixelColor(device, 482, 362);
3991     ok(color == 0x00000000, "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
3992
3993     /* 1.3 shader */
3994     color = getPixelColor(device, 478, 118);
3995     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
3996     color = getPixelColor(device, 482, 118);
3997     ok(color == 0x00000000, "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
3998     color = getPixelColor(device, 478, 122);
3999     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4000     color = getPixelColor(device, 482, 122);
4001     ok(color == 0x00000000, "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4002
4003     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4004     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4005     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4006     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4007     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4008     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4009
4010     hr = IDirect3DDevice9_BeginScene(device);
4011     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4012     if(SUCCEEDED(hr))
4013     {
4014         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4015         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4016         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4017         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4018
4019         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4020         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4021         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4022         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4023
4024         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4025         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4026         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4027         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4028
4029         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4030         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4031         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4032         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4033
4034         hr = IDirect3DDevice9_EndScene(device);
4035         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4036     }
4037     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4038     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4039
4040     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4041      * that we swapped the values in c1 and c2 to make the other tests return some color
4042      */
4043     color = getPixelColor(device, 158, 118);
4044     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4045     color = getPixelColor(device, 162, 118);
4046     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4047     color = getPixelColor(device, 158, 122);
4048     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4049     color = getPixelColor(device, 162, 122);
4050     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4051
4052     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4053     color = getPixelColor(device, 158, 358);
4054     ok(color == 0x0000ff00, "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4055     color = getPixelColor(device, 162, 358);
4056     ok(color == 0x0000ff00, "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4057     color = getPixelColor(device, 158, 362);
4058     ok(color == 0x0000ff00, "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4059     color = getPixelColor(device, 162, 362);
4060     ok(color == 0x0000ff00, "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4061
4062     /* 1.2 shader */
4063     color = getPixelColor(device, 478, 358);
4064     ok(color == 0x0000ff00, "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4065     color = getPixelColor(device, 482, 358);
4066     ok(color == 0x0000ff00, "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4067     color = getPixelColor(device, 478, 362);
4068     ok(color == 0x0000ff00, "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4069     color = getPixelColor(device, 482, 362);
4070     ok(color == 0x0000ff00, "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4071
4072     /* 1.3 shader */
4073     color = getPixelColor(device, 478, 118);
4074     ok(color == 0x0000ff00, "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4075     color = getPixelColor(device, 482, 118);
4076     ok(color == 0x0000ff00, "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4077     color = getPixelColor(device, 478, 122);
4078     ok(color == 0x0000ff00, "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4079     color = getPixelColor(device, 482, 122);
4080     ok(color == 0x0000ff00, "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4081
4082     IDirect3DPixelShader9_Release(shader_14_coissue);
4083     IDirect3DPixelShader9_Release(shader_13_coissue);
4084     IDirect3DPixelShader9_Release(shader_12_coissue);
4085     IDirect3DPixelShader9_Release(shader_11_coissue);
4086     IDirect3DPixelShader9_Release(shader_14);
4087     IDirect3DPixelShader9_Release(shader_13);
4088     IDirect3DPixelShader9_Release(shader_12);
4089     IDirect3DPixelShader9_Release(shader_11);
4090 }
4091
4092 static void nested_loop_test(IDirect3DDevice9 *device) {
4093     const DWORD shader_code[] = {
4094         0xffff0300,                                                             /* ps_3_0               */
4095         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4096         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4097         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4098         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4099         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4100         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4101         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4102         0x0000001d,                                                             /* endloop              */
4103         0x0000001d,                                                             /* endloop              */
4104         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4105         0x0000ffff                                                              /* end                  */
4106     };
4107     IDirect3DPixelShader9 *shader;
4108     HRESULT hr;
4109     DWORD color;
4110     const float quad[] = {
4111         -1.0,   -1.0,   0.1,
4112          1.0,   -1.0,   0.1,
4113         -1.0,    1.0,   0.1,
4114          1.0,    1.0,   0.1
4115     };
4116
4117     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4118     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4119     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4120     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4121     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4122     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4123     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4124     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4125
4126     hr = IDirect3DDevice9_BeginScene(device);
4127     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4128     if(SUCCEEDED(hr))
4129     {
4130         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4131         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4132         hr = IDirect3DDevice9_EndScene(device);
4133         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4134     }
4135     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4136     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4137
4138     color = getPixelColor(device, 360, 240);
4139     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4140        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4141
4142     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4143     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4144     IDirect3DPixelShader9_Release(shader);
4145 }
4146
4147 struct varying_test_struct
4148 {
4149     const DWORD             *shader_code;
4150     IDirect3DPixelShader9   *shader;
4151     DWORD                   color, color_rhw;
4152     const char              *name;
4153     BOOL                    todo, todo_rhw;
4154 };
4155
4156 struct hugeVertex
4157 {
4158     float pos_x,        pos_y,      pos_z,      rhw;
4159     float weight_1,     weight_2,   weight_3,   weight_4;
4160     float index_1,      index_2,    index_3,    index_4;
4161     float normal_1,     normal_2,   normal_3,   normal_4;
4162     float fog_1,        fog_2,      fog_3,      fog_4;
4163     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
4164     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
4165     float binormal_1,   binormal_2, binormal_3, binormal_4;
4166     float depth_1,      depth_2,    depth_3,    depth_4;
4167     DWORD diffuse, specular;
4168 };
4169
4170 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
4171     /* dcl_position: fails to compile */
4172     const DWORD blendweight_code[] = {
4173         0xffff0300,                             /* ps_3_0                   */
4174         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
4175         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4176         0x0000ffff                              /* end                      */
4177     };
4178     const DWORD blendindices_code[] = {
4179         0xffff0300,                             /* ps_3_0                   */
4180         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
4181         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4182         0x0000ffff                              /* end                      */
4183     };
4184     const DWORD normal_code[] = {
4185         0xffff0300,                             /* ps_3_0                   */
4186         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
4187         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4188         0x0000ffff                              /* end                      */
4189     };
4190     /* psize: fails? */
4191     const DWORD texcoord0_code[] = {
4192         0xffff0300,                             /* ps_3_0                   */
4193         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
4194         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4195         0x0000ffff                              /* end                      */
4196     };
4197     const DWORD tangent_code[] = {
4198         0xffff0300,                             /* ps_3_0                   */
4199         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
4200         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4201         0x0000ffff                              /* end                      */
4202     };
4203     const DWORD binormal_code[] = {
4204         0xffff0300,                             /* ps_3_0                   */
4205         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
4206         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4207         0x0000ffff                              /* end                      */
4208     };
4209     /* tessfactor: fails */
4210     /* positiont: fails */
4211     const DWORD color_code[] = {
4212         0xffff0300,                             /* ps_3_0                   */
4213         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
4214         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4215         0x0000ffff                              /* end                      */
4216     };
4217     const DWORD fog_code[] = {
4218         0xffff0300,                             /* ps_3_0                   */
4219         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
4220         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4221         0x0000ffff                              /* end                      */
4222     };
4223     const DWORD depth_code[] = {
4224         0xffff0300,                             /* ps_3_0                   */
4225         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
4226         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4227         0x0000ffff                              /* end                      */
4228     };
4229     const DWORD specular_code[] = {
4230         0xffff0300,                             /* ps_3_0                   */
4231         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
4232         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4233         0x0000ffff                              /* end                      */
4234     };
4235     /* sample: fails */
4236
4237     struct varying_test_struct tests[] = {
4238        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
4239        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
4240        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
4241        /* Why does dx not forward the texcoord? */
4242        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
4243        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
4244        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
4245        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
4246        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
4247        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
4248        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
4249     };
4250     /* Declare a monster vertex type :-) */
4251     static const D3DVERTEXELEMENT9 decl_elements[] = {
4252         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
4253         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
4254         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
4255         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
4256         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
4257         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
4258         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
4259         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
4260         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
4261         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
4262         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
4263         D3DDECL_END()
4264     };
4265     static const D3DVERTEXELEMENT9 decl_elements2[] = {
4266         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
4267         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
4268         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
4269         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
4270         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
4271         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
4272         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
4273         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
4274         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
4275         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
4276         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
4277         D3DDECL_END()
4278     };
4279     struct hugeVertex data[4] = {
4280         {
4281             -1.0,   -1.0,   0.1,    1.0,
4282              0.1,    0.1,   0.1,    0.1,
4283              0.2,    0.2,   0.2,    0.2,
4284              0.3,    0.3,   0.3,    0.3,
4285              0.4,    0.4,   0.4,    0.4,
4286              0.50,   0.55,  0.55,   0.55,
4287              0.6,    0.6,   0.6,    0.7,
4288              0.7,    0.7,   0.7,    0.6,
4289              0.8,    0.8,   0.8,    0.8,
4290              0xe6e6e6e6, /* 0.9 * 256 */
4291              0x224488ff  /* Nothing special */
4292         },
4293         {
4294              1.0,   -1.0,   0.1,    1.0,
4295              0.1,    0.1,   0.1,    0.1,
4296              0.2,    0.2,   0.2,    0.2,
4297              0.3,    0.3,   0.3,    0.3,
4298              0.4,    0.4,   0.4,    0.4,
4299              0.50,   0.55,  0.55,   0.55,
4300              0.6,    0.6,   0.6,    0.7,
4301              0.7,    0.7,   0.7,    0.6,
4302              0.8,    0.8,   0.8,    0.8,
4303              0xe6e6e6e6, /* 0.9 * 256 */
4304              0x224488ff /* Nothing special */
4305         },
4306         {
4307             -1.0,    1.0,   0.1,    1.0,
4308              0.1,    0.1,   0.1,    0.1,
4309              0.2,    0.2,   0.2,    0.2,
4310              0.3,    0.3,   0.3,    0.3,
4311              0.4,    0.4,   0.4,    0.4,
4312              0.50,   0.55,  0.55,   0.55,
4313              0.6,    0.6,   0.6,    0.7,
4314              0.7,    0.7,   0.7,    0.6,
4315              0.8,    0.8,   0.8,    0.8,
4316              0xe6e6e6e6, /* 0.9 * 256 */
4317              0x224488ff /* Nothing special */
4318         },
4319         {
4320              1.0,    1.0,   0.1,    1.0,
4321              0.1,    0.1,   0.1,    0.1,
4322              0.2,    0.2,   0.2,    0.2,
4323              0.3,    0.3,   0.3,    0.3,
4324              0.4,    0.4,   0.4,    0.4,
4325              0.50,   0.55,  0.55,   0.55,
4326              0.6,    0.6,   0.6,    0.7,
4327              0.7,    0.7,   0.7,    0.6,
4328              0.8,    0.8,   0.8,    0.8,
4329              0xe6e6e6e6, /* 0.9 * 256 */
4330              0x224488ff /* Nothing special */
4331         },
4332     };
4333     struct hugeVertex data2[4];
4334     IDirect3DVertexDeclaration9 *decl;
4335     IDirect3DVertexDeclaration9 *decl2;
4336     HRESULT hr;
4337     unsigned int i;
4338     DWORD color, r, g, b, r_e, g_e, b_e;
4339
4340     memcpy(data2, data, sizeof(data2));
4341     data2[0].pos_x = 0;     data2[0].pos_y = 0;
4342     data2[1].pos_x = 640;   data2[1].pos_y = 0;
4343     data2[2].pos_x = 0;     data2[2].pos_y = 480;
4344     data2[3].pos_x = 640;   data2[3].pos_y = 480;
4345
4346     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4347     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4348     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4349     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4350     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4351     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4352
4353     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4354     {
4355         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
4356         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
4357            tests[i].name, DXGetErrorString9(hr));
4358     }
4359
4360     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4361     {
4362         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4363         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4364
4365         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4366         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4367
4368         hr = IDirect3DDevice9_BeginScene(device);
4369         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4370         if(SUCCEEDED(hr))
4371         {
4372             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
4373             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4374             hr = IDirect3DDevice9_EndScene(device);
4375             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4376         }
4377         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4378         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4379
4380         color = getPixelColor(device, 360, 240);
4381         r = color & 0x00ff0000 >> 16;
4382         g = color & 0x0000ff00 >>  8;
4383         b = color & 0x000000ff;
4384         r_e = tests[i].color & 0x00ff0000 >> 16;
4385         g_e = tests[i].color & 0x0000ff00 >>  8;
4386         b_e = tests[i].color & 0x000000ff;
4387
4388         if(tests[i].todo) {
4389             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4390                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4391                          tests[i].name, color, tests[i].color);
4392         } else {
4393             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4394                "Test %s returned color 0x%08x, expected 0x%08x\n",
4395                tests[i].name, color, tests[i].color);
4396         }
4397     }
4398
4399     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4400     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4401     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4402     {
4403         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4404         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4405
4406         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4407         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4408
4409         hr = IDirect3DDevice9_BeginScene(device);
4410         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4411         if(SUCCEEDED(hr))
4412         {
4413             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
4414             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4415             hr = IDirect3DDevice9_EndScene(device);
4416             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4417         }
4418         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4419         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4420
4421         color = getPixelColor(device, 360, 240);
4422         r = color & 0x00ff0000 >> 16;
4423         g = color & 0x0000ff00 >>  8;
4424         b = color & 0x000000ff;
4425         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
4426         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
4427         b_e = tests[i].color_rhw & 0x000000ff;
4428
4429         if(tests[i].todo_rhw) {
4430             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
4431              * pipeline
4432              */
4433             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4434                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4435                          tests[i].name, color, tests[i].color_rhw);
4436         } else {
4437             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4438                "Test %s returned color 0x%08x, expected 0x%08x\n",
4439                tests[i].name, color, tests[i].color_rhw);
4440         }
4441     }
4442
4443     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4444     {
4445         IDirect3DPixelShader9_Release(tests[i].shader);
4446     }
4447
4448     IDirect3DVertexDeclaration9_Release(decl2);
4449     IDirect3DVertexDeclaration9_Release(decl);
4450 }
4451
4452 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
4453     static const DWORD ps_code[] = {
4454     0xffff0300,                                                             /* ps_3_0                       */
4455     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
4456     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
4457     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
4458     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
4459     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
4460     0x0200001f, 0x80000003, 0x900f0006,
4461     0x0200001f, 0x80000006, 0x900f0007,
4462     0x0200001f, 0x80000001, 0x900f0008,
4463     0x0200001f, 0x8000000c, 0x900f0009,
4464
4465     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4466     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
4467     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
4468     0x0000001d,                                                             /* endloop                      */
4469     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4470     0x0000ffff                                                              /* end                          */
4471     };
4472     static const DWORD vs_1_code[] = {
4473     0xfffe0101,                                                             /* vs_1_1                       */
4474     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4475     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
4476     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
4477     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
4478     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4479     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
4480     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
4481     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
4482     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
4483     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
4484     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
4485     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
4486     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
4487     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
4488     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
4489     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
4490     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
4491     0x0000ffff
4492     };
4493     DWORD vs_2_code[] = {
4494     0xfffe0200,                                                             /* vs_2_0                       */
4495     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4496     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
4497     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0   */
4498     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0   */
4499     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4500     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
4501     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
4502     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
4503     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
4504     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
4505     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
4506     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
4507     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
4508     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
4509     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
4510     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
4511     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
4512     0x0000ffff                                                              /* end                          */
4513     };
4514     /* TODO: Define normal, tangent, blendweight and depth here */
4515     static const DWORD vs_3_code[] = {
4516     0xfffe0300,                                                             /* vs_3_0                       */
4517     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4518     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
4519     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
4520     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
4521     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
4522     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
4523     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
4524     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
4525     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4526     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
4527     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
4528     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
4529     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
4530     0x0000ffff                                                              /* end                          */
4531     };
4532     float quad1[] =  {
4533         -1.0,   -1.0,   0.1,
4534          0.0,   -1.0,   0.1,
4535         -1.0,    0.0,   0.1,
4536          0.0,    0.0,   0.1
4537     };
4538     float quad2[] =  {
4539          0.0,   -1.0,   0.1,
4540          1.0,   -1.0,   0.1,
4541          0.0,    0.0,   0.1,
4542          1.0,    0.0,   0.1
4543     };
4544     float quad3[] =  {
4545         -1.0,    0.0,   0.1,
4546          0.0,    0.0,   0.1,
4547         -1.0,    1.0,   0.1,
4548          0.0,    1.0,   0.1
4549     };
4550
4551     HRESULT hr;
4552     DWORD color;
4553     IDirect3DPixelShader9 *pixelshader = NULL;
4554     IDirect3DVertexShader9 *vs_1_shader = NULL;
4555     IDirect3DVertexShader9 *vs_2_shader = NULL;
4556     IDirect3DVertexShader9 *vs_3_shader = NULL;
4557
4558     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
4559
4560     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
4561     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4562     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
4563     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4564     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
4565     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4566     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
4567     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4568     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
4569     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4570     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4571
4572     hr = IDirect3DDevice9_BeginScene(device);
4573     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4574     if(SUCCEEDED(hr))
4575     {
4576         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
4577         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4579         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4580
4581         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
4582         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4583         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4584         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4585
4586         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
4587         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4589         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4590
4591         hr = IDirect3DDevice9_EndScene(device);
4592         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4593     }
4594     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4595     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4596
4597     color = getPixelColor(device, 160, 120);
4598     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4599        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
4600        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4601        "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
4602     color = getPixelColor(device, 160, 360);
4603     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4604        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4605        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4606        "vs_1_1 returned color 0x%08x, expected 0x00808080\n", color);
4607     color = getPixelColor(device, 480, 360);
4608     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4609        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4610        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4611        "vs_2_0 returned color 0x%08x, expected 0x00000000\n", color);
4612
4613     /* cleanup */
4614     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4615     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4616     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4617     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4618     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
4619     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
4620     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
4621     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
4622 }
4623
4624 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
4625     static const DWORD vs_code[] = {
4626     0xfffe0300,                                                             /* vs_3_0                       */
4627     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4628     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
4629     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
4630     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
4631     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
4632     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
4633     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
4634     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
4635     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
4636     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
4637     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
4638     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
4639     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
4640
4641     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
4642     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
4643     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
4644     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
4645     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
4646     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
4647     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
4648     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
4649     0x0000ffff                                                              /* end                          */
4650     };
4651     static const DWORD ps_1_code[] = {
4652     0xffff0104,                                                             /* ps_1_4                       */
4653     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
4654     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
4655     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
4656     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
4657     0x0000ffff                                                              /* end                          */
4658     };
4659     static const DWORD ps_2_code[] = {
4660     0xffff0200,                                                             /* ps_2_0                       */
4661     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
4662     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
4663     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
4664
4665     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
4666     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
4667     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4668     0x0000ffff                                                              /* end                          */
4669     };
4670     static const DWORD ps_3_code[] = {
4671     0xffff0300,                                                             /* ps_3_0                       */
4672     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
4673     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
4674     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
4675
4676     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
4677     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
4678     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
4679     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4680     0x0000ffff                                                              /* end                          */
4681     };
4682
4683     float quad1[] =  {
4684         -1.0,   -1.0,   0.1,
4685          0.0,   -1.0,   0.1,
4686         -1.0,    0.0,   0.1,
4687          0.0,    0.0,   0.1
4688     };
4689     float quad2[] =  {
4690          0.0,   -1.0,   0.1,
4691          1.0,   -1.0,   0.1,
4692          0.0,    0.0,   0.1,
4693          1.0,    0.0,   0.1
4694     };
4695     float quad3[] =  {
4696         -1.0,    0.0,   0.1,
4697          0.0,    0.0,   0.1,
4698         -1.0,    1.0,   0.1,
4699          0.0,    1.0,   0.1
4700     };
4701     float quad4[] =  {
4702          0.0,    0.0,   0.1,
4703          1.0,    0.0,   0.1,
4704          0.0,    1.0,   0.1,
4705          1.0,    1.0,   0.1
4706     };
4707
4708     HRESULT hr;
4709     DWORD color;
4710     IDirect3DVertexShader9 *vertexshader = NULL;
4711     IDirect3DPixelShader9 *ps_1_shader = NULL;
4712     IDirect3DPixelShader9 *ps_2_shader = NULL;
4713     IDirect3DPixelShader9 *ps_3_shader = NULL;
4714     IDirect3DTexture9 *texture = NULL;
4715     D3DLOCKED_RECT lr;
4716     unsigned int x, y;
4717
4718     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4719
4720     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
4721     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4722     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4723     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
4724     for(y = 0; y < 512; y++) {
4725         for(x = 0; x < 512; x++) {
4726             double r_f = (double) x / (double) 512;
4727             double g_f = (double) y / (double) 512;
4728             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
4729             unsigned short r = (unsigned short) (r_f * 65535.0);
4730             unsigned short g = (unsigned short) (g_f * 65535.0);
4731             dst[0] = r;
4732             dst[1] = g;
4733             dst[2] = 0;
4734             dst[3] = 65535;
4735         }
4736     }
4737     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4738     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4739
4740     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
4741     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4742     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
4743     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4744     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4746     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
4747     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4748     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
4749     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4750     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4751
4752     hr = IDirect3DDevice9_BeginScene(device);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4754     if(SUCCEEDED(hr))
4755     {
4756         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
4757         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4758         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4759         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4760
4761         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
4762         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4763         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4764         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4765
4766         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
4767         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4768         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4769         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4770
4771         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4772         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4773         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4774         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4775         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4776         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
4777         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4778         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
4779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
4780         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4781
4782         hr = IDirect3DDevice9_EndScene(device);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4784     }
4785     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4786     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4787
4788     color = getPixelColor(device, 160, 120);
4789     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
4790        (color & 0x0000ff00) == 0x0000ff00 &&
4791        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
4792        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
4793     color = getPixelColor(device, 160, 360);
4794     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4795        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
4796        (color & 0x000000ff) == 0x00000000,
4797        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
4798     color = getPixelColor(device, 480, 360);
4799     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4800        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4801        (color & 0x000000ff) == 0x00000000,
4802        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
4803     color = getPixelColor(device, 480, 160);
4804     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4805        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4806        (color & 0x000000ff) == 0x00000000,
4807        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
4808
4809     /* cleanup */
4810     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4811     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4812     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4813     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4814     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4815     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4816     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
4817     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
4818     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
4819     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
4820     if(texture) IDirect3DTexture9_Release(texture);
4821 }
4822
4823 void test_compare_instructions(IDirect3DDevice9 *device)
4824 {
4825     DWORD shader_sge_vec_code[] = {
4826         0xfffe0101,                                         /* vs_1_1                   */
4827         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4828         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4829         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4830         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
4831         0x0000ffff                                          /* end                      */
4832     };
4833     DWORD shader_slt_vec_code[] = {
4834         0xfffe0101,                                         /* vs_1_1                   */
4835         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4836         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4837         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4838         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
4839         0x0000ffff                                          /* end                      */
4840     };
4841     DWORD shader_sge_scalar_code[] = {
4842         0xfffe0101,                                         /* vs_1_1                   */
4843         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4844         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4845         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4846         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
4847         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
4848         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
4849         0x0000ffff                                          /* end                      */
4850     };
4851     DWORD shader_slt_scalar_code[] = {
4852         0xfffe0101,                                         /* vs_1_1                   */
4853         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4854         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4855         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4856         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
4857         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
4858         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
4859         0x0000ffff                                          /* end                      */
4860     };
4861     IDirect3DVertexShader9 *shader_sge_vec;
4862     IDirect3DVertexShader9 *shader_slt_vec;
4863     IDirect3DVertexShader9 *shader_sge_scalar;
4864     IDirect3DVertexShader9 *shader_slt_scalar;
4865     HRESULT hr, color;
4866     float quad1[] =  {
4867         -1.0,   -1.0,   0.1,
4868          0.0,   -1.0,   0.1,
4869         -1.0,    0.0,   0.1,
4870          0.0,    0.0,   0.1
4871     };
4872     float quad2[] =  {
4873          0.0,   -1.0,   0.1,
4874          1.0,   -1.0,   0.1,
4875          0.0,    0.0,   0.1,
4876          1.0,    0.0,   0.1
4877     };
4878     float quad3[] =  {
4879         -1.0,    0.0,   0.1,
4880          0.0,    0.0,   0.1,
4881         -1.0,    1.0,   0.1,
4882          0.0,    1.0,   0.1
4883     };
4884     float quad4[] =  {
4885          0.0,    0.0,   0.1,
4886          1.0,    0.0,   0.1,
4887          0.0,    1.0,   0.1,
4888          1.0,    1.0,   0.1
4889     };
4890     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
4891     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
4892
4893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4894
4895     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
4896     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4897     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
4898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4899     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
4900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4901     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
4902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4903     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
4904     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4905     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
4906     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4907     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4908     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4909
4910     hr = IDirect3DDevice9_BeginScene(device);
4911     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4912     if(SUCCEEDED(hr))
4913     {
4914         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
4915         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4916         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4917         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4918
4919         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
4920         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4921         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4922         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4923
4924         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
4925         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4927         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4928
4929         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
4930         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4931
4932         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
4933         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4934         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
4935         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4936
4937         hr = IDirect3DDevice9_EndScene(device);
4938         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4939     }
4940
4941     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4942     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4943
4944     color = getPixelColor(device, 160, 360);
4945     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
4946     color = getPixelColor(device, 480, 360);
4947     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
4948     color = getPixelColor(device, 160, 120);
4949     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
4950     color = getPixelColor(device, 480, 160);
4951     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
4952
4953     IDirect3DVertexShader9_Release(shader_sge_vec);
4954     IDirect3DVertexShader9_Release(shader_slt_vec);
4955     IDirect3DVertexShader9_Release(shader_sge_scalar);
4956     IDirect3DVertexShader9_Release(shader_slt_scalar);
4957 }
4958
4959 void test_vshader_input(IDirect3DDevice9 *device)
4960 {
4961     DWORD swapped_shader_code_3[] = {
4962         0xfffe0300,                                         /* vs_3_0               */
4963         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
4964         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
4965         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4966         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
4967         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
4968         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
4969         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
4970         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
4971         0x0000ffff                                          /* end                  */
4972     };
4973     DWORD swapped_shader_code_1[] = {
4974         0xfffe0101,                                         /* vs_1_1               */
4975         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4976         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
4977         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
4978         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
4979         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
4980         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
4981         0x0000ffff                                          /* end                  */
4982     };
4983     DWORD swapped_shader_code_2[] = {
4984         0xfffe0200,                                         /* vs_2_0               */
4985         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4986         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
4987         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
4988         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
4989         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
4990         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
4991         0x0000ffff                                          /* end                  */
4992     };
4993     DWORD texcoord_color_shader_code_3[] = {
4994         0xfffe0300,                                         /* vs_3_0               */
4995         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
4996         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
4997         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4998         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
4999         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5000         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5001         0x0000ffff                                          /* end                  */
5002     };
5003     DWORD texcoord_color_shader_code_2[] = {
5004         0xfffe0200,                                         /* vs_2_0               */
5005         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5006         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5007         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5008         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5009         0x0000ffff                                          /* end                  */
5010     };
5011     DWORD texcoord_color_shader_code_1[] = {
5012         0xfffe0101,                                         /* vs_1_1               */
5013         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5014         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5015         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5016         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5017         0x0000ffff                                          /* end                  */
5018     };
5019     DWORD color_color_shader_code_3[] = {
5020         0xfffe0300,                                         /* vs_3_0               */
5021         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5022         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5023         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5024         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5025         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5026         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5027         0x0000ffff                                          /* end                  */
5028     };
5029     DWORD color_color_shader_code_2[] = {
5030         0xfffe0200,                                         /* vs_2_0               */
5031         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5032         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5033         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5034         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5035         0x0000ffff                                          /* end                  */
5036     };
5037     DWORD color_color_shader_code_1[] = {
5038         0xfffe0101,                                         /* vs_1_1               */
5039         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5040         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5041         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5042         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5043         0x0000ffff                                          /* end                  */
5044     };
5045     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5046     HRESULT hr;
5047     DWORD color, r, g, b;
5048     float quad1[] =  {
5049         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5050          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5051         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5052          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5053     };
5054     float quad2[] =  {
5055          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5056          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5057          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5058          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5059     };
5060     float quad3[] =  {
5061         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5062          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5063         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5064          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5065     };
5066     float quad4[] =  {
5067          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5068          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5069          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5070          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5071     };
5072     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5073         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5074         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5075         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5076         D3DDECL_END()
5077     };
5078     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5079         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5080         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5081         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5082         D3DDECL_END()
5083     };
5084     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5085         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5086         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5087         D3DDECL_END()
5088     };
5089     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5090         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5091         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5092         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5093         D3DDECL_END()
5094     };
5095     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5096         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5097         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5098         D3DDECL_END()
5099     };
5100     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5101         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5102         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5103         D3DDECL_END()
5104     };
5105     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5106         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5107         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5108         D3DDECL_END()
5109     };
5110     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5111         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5112         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5113         D3DDECL_END()
5114     };
5115     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5116     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5117     unsigned int i;
5118     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5119     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5120
5121     struct vertex quad1_color[] =  {
5122        {-1.0,   -1.0,   0.1,    0x00ff8040},
5123        { 0.0,   -1.0,   0.1,    0x00ff8040},
5124        {-1.0,    0.0,   0.1,    0x00ff8040},
5125        { 0.0,    0.0,   0.1,    0x00ff8040}
5126     };
5127     struct vertex quad2_color[] =  {
5128        { 0.0,   -1.0,   0.1,    0x00ff8040},
5129        { 1.0,   -1.0,   0.1,    0x00ff8040},
5130        { 0.0,    0.0,   0.1,    0x00ff8040},
5131        { 1.0,    0.0,   0.1,    0x00ff8040}
5132     };
5133     struct vertex quad3_color[] =  {
5134        {-1.0,    0.0,   0.1,    0x00ff8040},
5135        { 0.0,    0.0,   0.1,    0x00ff8040},
5136        {-1.0,    1.0,   0.1,    0x00ff8040},
5137        { 0.0,    1.0,   0.1,    0x00ff8040}
5138     };
5139     float quad4_color[] =  {
5140          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5141          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5142          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5143          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5144     };
5145
5146     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
5147     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5148     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
5149     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5150     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
5151     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5152     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
5153     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5154
5155     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
5156     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5157     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
5158     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5159     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
5160     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5161     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
5162     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5163
5164     for(i = 1; i <= 3; i++) {
5165         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5166         if(i == 3) {
5167             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
5168             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5169         } else if(i == 2){
5170             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
5171             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5172         } else if(i == 1) {
5173             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
5174             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5175         }
5176
5177         hr = IDirect3DDevice9_BeginScene(device);
5178         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5179         if(SUCCEEDED(hr))
5180         {
5181             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5182             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5183
5184             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5185             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5186             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
5187             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5188
5189             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5190             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5191             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
5192             if(i == 3 || i == 2) {
5193                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5194             } else if(i == 1) {
5195                 /* Succeeds or fails, depending on SW or HW vertex processing */
5196                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5197             }
5198
5199             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
5200             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5201             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
5202             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5203
5204             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
5205             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5206             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
5207             if(i == 3 || i == 2) {
5208                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5209             } else if(i == 1) {
5210                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
5211             }
5212
5213             hr = IDirect3DDevice9_EndScene(device);
5214             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5215         }
5216
5217         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5218         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5219
5220         if(i == 3 || i == 2) {
5221             color = getPixelColor(device, 160, 360);
5222             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5223                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5224
5225             /* The last value of the read but undefined stream is used */
5226             color = getPixelColor(device, 480, 360);
5227             ok(color == 0x00FFFF00, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5228             color = getPixelColor(device, 160, 120);
5229             ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081,
5230                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5231
5232             color = getPixelColor(device, 480, 160);
5233             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5234         } else if(i == 1) {
5235             color = getPixelColor(device, 160, 360);
5236             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5237                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5238             color = getPixelColor(device, 480, 360);
5239             /* Accept the clear color as well in this case, since SW VP returns an error */
5240             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5241             color = getPixelColor(device, 160, 120);
5242             ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
5243                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5244             color = getPixelColor(device, 480, 160);
5245             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5246         }
5247
5248         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
5249         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5250
5251         /* Now find out if the whole streams are re-read, or just the last active value for the
5252          * vertices is used.
5253          */
5254         hr = IDirect3DDevice9_BeginScene(device);
5255         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5256         if(SUCCEEDED(hr))
5257         {
5258             float quad1_modified[] =  {
5259                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5260                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
5261                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
5262                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
5263             };
5264             float quad2_modified[] =  {
5265                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5266                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5267                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5268                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5269             };
5270
5271             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5272             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5273
5274             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5275             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5276             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
5277             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5278
5279             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5280             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5281             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
5282             if(i == 3 || i == 2) {
5283                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5284             } else if(i == 1) {
5285                 /* Succeeds or fails, depending on SW or HW vertex processing */
5286                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5287             }
5288
5289             hr = IDirect3DDevice9_EndScene(device);
5290             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5291         }
5292         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5293         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5294
5295         color = getPixelColor(device, 480, 360);
5296         /* vs_1_1 may fail, accept the clear color
5297          *
5298          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
5299          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
5300          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
5301          * refrast's result.
5302          *
5303          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
5304          */
5305         ok(color == 0x000000FF || color == 0x00808080,
5306            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF\n", color);
5307         color = getPixelColor(device, 160, 120);
5308
5309         IDirect3DDevice9_SetVertexShader(device, NULL);
5310         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5311
5312         IDirect3DVertexShader9_Release(swapped_shader);
5313     }
5314
5315     for(i = 1; i <= 3; i++) {
5316         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5317         if(i == 3) {
5318             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
5319             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5320             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
5321             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5322         } else if(i == 2){
5323             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
5324             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5325             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
5326             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5327         } else if(i == 1) {
5328             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
5329             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5330             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
5331             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5332         }
5333
5334         hr = IDirect3DDevice9_BeginScene(device);
5335         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5336         if(SUCCEEDED(hr))
5337         {
5338             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
5339             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5340             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
5341             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5342             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
5343             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5344
5345             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
5346             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5347
5348             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
5349             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5350             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
5351             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5352             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
5353             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5354
5355             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
5356             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5357             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
5358             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5359             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
5360             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5361
5362             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
5363             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5364             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
5365             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5366
5367             hr = IDirect3DDevice9_EndScene(device);
5368             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5369         }
5370         IDirect3DDevice9_SetVertexShader(device, NULL);
5371         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5372
5373         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5374         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5375
5376         color = getPixelColor(device, 160, 360);
5377         r = (color & 0x00ff0000) >> 16;
5378         g = (color & 0x0000ff00) >>  8;
5379         b = (color & 0x000000ff) >>  0;
5380         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5381            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
5382         color = getPixelColor(device, 480, 360);
5383         r = (color & 0x00ff0000) >> 16;
5384         g = (color & 0x0000ff00) >>  8;
5385         b = (color & 0x000000ff) >>  0;
5386         ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
5387            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
5388         color = getPixelColor(device, 160, 120);
5389         r = (color & 0x00ff0000) >> 16;
5390         g = (color & 0x0000ff00) >>  8;
5391         b = (color & 0x000000ff) >>  0;
5392         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5393            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
5394         color = getPixelColor(device, 480, 160);
5395         r = (color & 0x00ff0000) >> 16;
5396         g = (color & 0x0000ff00) >>  8;
5397         b = (color & 0x000000ff) >>  0;
5398         ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
5399            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
5400
5401         IDirect3DVertexShader9_Release(texcoord_color_shader);
5402         IDirect3DVertexShader9_Release(color_color_shader);
5403     }
5404
5405     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
5406     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
5407     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
5408     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
5409
5410     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
5411     IDirect3DVertexDeclaration9_Release(decl_color_color);
5412     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
5413     IDirect3DVertexDeclaration9_Release(decl_color_float);
5414 }
5415
5416 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
5417 {
5418     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
5419      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
5420      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
5421      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
5422      * 0.73
5423      *
5424      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
5425      * so use shaders for this task
5426      */
5427     IDirect3DPixelShader9 *pshader;
5428     IDirect3DVertexShader9 *vshader;
5429     IDirect3D9 *d3d;
5430     DWORD vshader_code[] = {
5431         0xfffe0101,                                                             /* vs_1_1                       */
5432         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5433         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
5434         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5435         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
5436         0x0000ffff                                                              /* end                          */
5437     };
5438     DWORD pshader_code[] = {
5439         0xffff0101,                                                             /* ps_1_1                       */
5440         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5441         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5442         0x0000ffff                                                              /* end                          */
5443     };
5444     const float quad[] = {
5445        -1.0,   -1.0,    0.1,
5446         1.0,   -1.0,    0.1,
5447        -1.0,    1.0,    0.1,
5448         1.0,    1.0,    0.1
5449     };
5450     HRESULT hr;
5451     DWORD color;
5452
5453     IDirect3DDevice9_GetDirect3D(device, &d3d);
5454     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5455                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
5456                                     D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
5457         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
5458         IDirect3D9_Release(d3d);
5459         return;
5460     }
5461     IDirect3D9_Release(d3d);
5462
5463     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5464     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5465
5466     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5467     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5468     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
5469     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5470     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
5471     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5472     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
5473     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5474     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
5475     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5476
5477     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5478     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5479     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
5480     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5481     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5482     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
5483     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5484     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5485     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
5486     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5487
5488     hr = IDirect3DDevice9_BeginScene(device);
5489     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5490     if(SUCCEEDED(hr)) {
5491         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
5492         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5493
5494         hr = IDirect3DDevice9_EndScene(device);
5495         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5496     }
5497
5498     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5499     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5500     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5501     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5502     IDirect3DPixelShader9_Release(pshader);
5503     IDirect3DVertexShader9_Release(vshader);
5504
5505     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
5506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5507     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
5508     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5509
5510     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5511     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5512     color = getPixelColor(device, 160, 360);
5513     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
5514        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
5515 }
5516
5517 static void alpha_test(IDirect3DDevice9 *device)
5518 {
5519     HRESULT hr;
5520     IDirect3DTexture9 *offscreenTexture;
5521     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
5522     DWORD color, red, green, blue;
5523
5524     struct vertex quad1[] =
5525     {
5526         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
5527         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
5528         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
5529         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
5530     };
5531     struct vertex quad2[] =
5532     {
5533         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
5534         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
5535         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
5536         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
5537     };
5538     static const float composite_quad[][5] = {
5539         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
5540         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
5541         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
5542         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
5543     };
5544
5545     /* Clear the render target with alpha = 0.5 */
5546     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5547     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5548
5549     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
5550     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
5551
5552     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5553     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
5554     if(!backbuffer) {
5555         goto out;
5556     }
5557
5558     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
5559     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
5560     if(!offscreen) {
5561         goto out;
5562     }
5563
5564     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
5565     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5566
5567     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5568     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5569     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5570     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5571     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
5572     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
5573     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
5574     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
5575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5576     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5577
5578     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
5579     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5580     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
5581
5582         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
5583          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
5584          * the input alpha
5585          *
5586          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
5587          * They give essentially ZERO and ONE blend factors
5588          */
5589         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5590         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5591         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5592         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5593         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5594         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5595
5596         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5597         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5598         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5599         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5600         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5601         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5602
5603         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
5604          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
5605          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
5606          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
5607          * vertices
5608          */
5609         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
5610         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5611         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5612         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5613
5614         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5615         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5616         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5617         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5618         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5619         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5620
5621         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5622         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5623         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5624         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5625         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5626         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5627
5628         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
5629         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5630
5631         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
5632          * Disable alpha blending for the final composition
5633          */
5634         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
5635         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5636         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5637         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5638
5639         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
5640         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5641         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
5642         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5643         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5644         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5645
5646         hr = IDirect3DDevice9_EndScene(device);
5647         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
5648     }
5649
5650     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5651
5652     color = getPixelColor(device, 160, 360);
5653     red =   (color & 0x00ff0000) >> 16;
5654     green = (color & 0x0000ff00) >>  8;
5655     blue =  (color & 0x000000ff);
5656     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
5657        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
5658
5659     color = getPixelColor(device, 160, 120);
5660     red =   (color & 0x00ff0000) >> 16;
5661     green = (color & 0x0000ff00) >>  8;
5662     blue =  (color & 0x000000ff);
5663     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
5664        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
5665
5666     color = getPixelColor(device, 480, 360);
5667     red =   (color & 0x00ff0000) >> 16;
5668     green = (color & 0x0000ff00) >>  8;
5669     blue =  (color & 0x000000ff);
5670     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
5671        "SRCALPHA on texture returned color %08x, expected bar\n", color);
5672
5673     color = getPixelColor(device, 480, 120);
5674     red =   (color & 0x00ff0000) >> 16;
5675     green = (color & 0x0000ff00) >>  8;
5676     blue =  (color & 0x000000ff);
5677     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
5678        "DSTALPHA on texture returned color %08x, expected foo\n", color);
5679
5680     out:
5681     /* restore things */
5682     if(backbuffer) {
5683         IDirect3DSurface9_Release(backbuffer);
5684     }
5685     if(offscreenTexture) {
5686         IDirect3DTexture9_Release(offscreenTexture);
5687     }
5688     if(offscreen) {
5689         IDirect3DSurface9_Release(offscreen);
5690     }
5691 }
5692
5693 struct vertex_shortcolor {
5694     float x, y, z;
5695     unsigned short r, g, b, a;
5696 };
5697 struct vertex_floatcolor {
5698     float x, y, z;
5699     float r, g, b, a;
5700 };
5701
5702 static void fixed_function_decl_test(IDirect3DDevice9 *device)
5703 {
5704     HRESULT hr;
5705     BOOL s_ok, ub_ok, f_ok;
5706     DWORD color, size, i;
5707     void *data;
5708     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
5709         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5710         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5711         D3DDECL_END()
5712     };
5713     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
5714         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5715         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5716         D3DDECL_END()
5717     };
5718     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
5719         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5720         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5721         D3DDECL_END()
5722     };
5723     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
5724         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5725         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5726         D3DDECL_END()
5727     };
5728     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
5729         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5730         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5731         D3DDECL_END()
5732     };
5733     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
5734         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5735         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5736         D3DDECL_END()
5737     };
5738     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
5739         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5740         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5741         D3DDECL_END()
5742     };
5743     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
5744     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
5745     IDirect3DVertexBuffer9 *vb, *vb2;
5746     struct vertex quad1[] =                             /* D3DCOLOR */
5747     {
5748         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
5749         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
5750         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
5751         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
5752     };
5753     struct vertex quad2[] =                             /* UBYTE4N */
5754     {
5755         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
5756         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
5757         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
5758         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
5759     };
5760     struct vertex_shortcolor quad3[] =                  /* short */
5761     {
5762         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5763         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5764         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5765         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5766     };
5767     struct vertex_floatcolor quad4[] =
5768     {
5769         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5770         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5771         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5772         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5773     };
5774     DWORD colors[] = {
5775         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5776         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5777         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5778         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5779         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5780         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5781         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5782         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5783         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5784         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5785         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5786         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5787         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5788         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5789         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5790         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5791     };
5792     float quads[] = {
5793         -1.0,   -1.0,     0.1,
5794         -1.0,    0.0,     0.1,
5795          0.0,   -1.0,     0.1,
5796          0.0,    0.0,     0.1,
5797
5798          0.0,   -1.0,     0.1,
5799          0.0,    0.0,     0.1,
5800          1.0,   -1.0,     0.1,
5801          1.0,    0.0,     0.1,
5802
5803          0.0,    0.0,     0.1,
5804          0.0,    1.0,     0.1,
5805          1.0,    0.0,     0.1,
5806          1.0,    1.0,     0.1,
5807
5808         -1.0,    0.0,     0.1,
5809         -1.0,    1.0,     0.1,
5810          0.0,    0.0,     0.1,
5811          0.0,    1.0,     0.1
5812     };
5813     struct tvertex quad_transformed[] = {
5814        {  90,    110,     0.1,      2.0,        0x00ffff00},
5815        { 570,    110,     0.1,      2.0,        0x00ffff00},
5816        {  90,    300,     0.1,      2.0,        0x00ffff00},
5817        { 570,    300,     0.1,      2.0,        0x00ffff00}
5818     };
5819     D3DCAPS9 caps;
5820
5821     memset(&caps, 0, sizeof(caps));
5822     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5823     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
5824
5825     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5826     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5827
5828     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
5829     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5830     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
5831     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
5832     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
5833     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5834     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
5835         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
5836         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5837         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
5838         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5839     } else {
5840         trace("D3DDTCAPS_UBYTE4N not supported\n");
5841         dcl_ubyte_2 = NULL;
5842         dcl_ubyte = NULL;
5843     }
5844     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
5845     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5846     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
5847     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5848
5849     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
5850     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
5851                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
5852     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
5853
5854     hr = IDirect3DDevice9_BeginScene(device);
5855     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5856     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
5857     if(SUCCEEDED(hr)) {
5858         if(dcl_color) {
5859             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
5860             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5861             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5862             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5863         }
5864
5865         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
5866          * accepts them, the nvidia driver accepts them all. All those differences even though we're
5867          * using software vertex processing. Doh!
5868          */
5869         if(dcl_ubyte) {
5870             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
5871             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5872             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5873             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5874             ub_ok = SUCCEEDED(hr);
5875         }
5876
5877         if(dcl_short) {
5878             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
5879             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5880             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
5881             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5882             s_ok = SUCCEEDED(hr);
5883         }
5884
5885         if(dcl_float) {
5886             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
5887             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5888             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
5889             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5890             f_ok = SUCCEEDED(hr);
5891         }
5892
5893         hr = IDirect3DDevice9_EndScene(device);
5894         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
5895     }
5896
5897     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5898     if(dcl_short) {
5899         color = getPixelColor(device, 480, 360);
5900         ok(color == 0x000000ff || !s_ok,
5901            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
5902     }
5903     if(dcl_ubyte) {
5904         color = getPixelColor(device, 160, 120);
5905         ok(color == 0x0000ffff || !ub_ok,
5906            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
5907     }
5908     if(dcl_color) {
5909         color = getPixelColor(device, 160, 360);
5910         ok(color == 0x00ffff00,
5911            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
5912     }
5913     if(dcl_float) {
5914         color = getPixelColor(device, 480, 120);
5915         ok(color == 0x00ff0000 || !f_ok,
5916            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
5917     }
5918
5919     /* The following test with vertex buffers doesn't serve to find out new information from windows.
5920      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
5921      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
5922      * whether the immediate mode code works
5923      */
5924     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
5925     hr = IDirect3DDevice9_BeginScene(device);
5926     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5927     if(SUCCEEDED(hr)) {
5928         if(dcl_color) {
5929             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
5930             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5931             memcpy(data, quad1, sizeof(quad1));
5932             hr = IDirect3DVertexBuffer9_Unlock(vb);
5933             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5934             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
5935             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5936             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
5937             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5938             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5939             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5940         }
5941
5942         if(dcl_ubyte) {
5943             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
5944             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5945             memcpy(data, quad2, sizeof(quad2));
5946             hr = IDirect3DVertexBuffer9_Unlock(vb);
5947             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5948             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
5949             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5950             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
5951             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5952             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5953             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5954                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5955             ub_ok = SUCCEEDED(hr);
5956         }
5957
5958         if(dcl_short) {
5959             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
5960             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5961             memcpy(data, quad3, sizeof(quad3));
5962             hr = IDirect3DVertexBuffer9_Unlock(vb);
5963             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5964             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
5965             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5966             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
5967             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5968             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5969             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5970                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5971             s_ok = SUCCEEDED(hr);
5972         }
5973
5974         if(dcl_float) {
5975             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
5976             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5977             memcpy(data, quad4, sizeof(quad4));
5978             hr = IDirect3DVertexBuffer9_Unlock(vb);
5979             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5980             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
5981             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5982             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
5983             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5984             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5985             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5986                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5987             f_ok = SUCCEEDED(hr);
5988         }
5989
5990         hr = IDirect3DDevice9_EndScene(device);
5991         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
5992     }
5993
5994     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
5995     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5996     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5997     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5998
5999     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6000     if(dcl_short) {
6001         color = getPixelColor(device, 480, 360);
6002         ok(color == 0x000000ff || !s_ok,
6003            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6004     }
6005     if(dcl_ubyte) {
6006         color = getPixelColor(device, 160, 120);
6007         ok(color == 0x0000ffff || !ub_ok,
6008            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6009     }
6010     if(dcl_color) {
6011         color = getPixelColor(device, 160, 360);
6012         ok(color == 0x00ffff00,
6013            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6014     }
6015     if(dcl_float) {
6016         color = getPixelColor(device, 480, 120);
6017         ok(color == 0x00ff0000 || !f_ok,
6018            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
6019     }
6020
6021     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6022     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
6023
6024     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
6025     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6026     memcpy(data, quad_transformed, sizeof(quad_transformed));
6027     hr = IDirect3DVertexBuffer9_Unlock(vb);
6028     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6029
6030     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
6031     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6032
6033     hr = IDirect3DDevice9_BeginScene(device);
6034     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6035     if(SUCCEEDED(hr)) {
6036         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
6037         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6038         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6039         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6040
6041         hr = IDirect3DDevice9_EndScene(device);
6042         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6043     }
6044
6045     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6046     color = getPixelColor(device, 88, 108);
6047     ok(color == 0x000000ff,
6048        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
6049     color = getPixelColor(device, 92, 108);
6050     ok(color == 0x000000ff,
6051        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
6052     color = getPixelColor(device, 88, 112);
6053     ok(color == 0x000000ff,
6054        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
6055     color = getPixelColor(device, 92, 112);
6056     ok(color == 0x00ffff00,
6057        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
6058
6059     color = getPixelColor(device, 568, 108);
6060     ok(color == 0x000000ff,
6061        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
6062     color = getPixelColor(device, 572, 108);
6063     ok(color == 0x000000ff,
6064        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
6065     color = getPixelColor(device, 568, 112);
6066     ok(color == 0x00ffff00,
6067        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
6068     color = getPixelColor(device, 572, 112);
6069     ok(color == 0x000000ff,
6070        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
6071
6072     color = getPixelColor(device, 88, 298);
6073     ok(color == 0x000000ff,
6074        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
6075     color = getPixelColor(device, 92, 298);
6076     ok(color == 0x00ffff00,
6077        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
6078     color = getPixelColor(device, 88, 302);
6079     ok(color == 0x000000ff,
6080        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
6081     color = getPixelColor(device, 92, 302);
6082     ok(color == 0x000000ff,
6083        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
6084
6085     color = getPixelColor(device, 568, 298);
6086     ok(color == 0x00ffff00,
6087        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
6088     color = getPixelColor(device, 572, 298);
6089     ok(color == 0x000000ff,
6090        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
6091     color = getPixelColor(device, 568, 302);
6092     ok(color == 0x000000ff,
6093        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
6094     color = getPixelColor(device, 572, 302);
6095     ok(color == 0x000000ff,
6096        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
6097
6098     /* This test is pointless without those two declarations: */
6099     if((!dcl_color_2) || (!dcl_ubyte_2)) {
6100         skip("color-ubyte switching test declarations aren't supported\n");
6101         goto out;
6102     }
6103
6104     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
6105     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6106     memcpy(data, quads, sizeof(quads));
6107     hr = IDirect3DVertexBuffer9_Unlock(vb);
6108     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6109     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
6110                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
6111     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6112     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
6113     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6114     memcpy(data, colors, sizeof(colors));
6115     hr = IDirect3DVertexBuffer9_Unlock(vb2);
6116     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6117
6118     for(i = 0; i < 2; i++) {
6119         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6120         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
6121
6122         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
6123         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6124         if(i == 0) {
6125             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
6126         } else {
6127             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
6128         }
6129         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6130
6131         hr = IDirect3DDevice9_BeginScene(device);
6132         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6133         ub_ok = FALSE;
6134         if(SUCCEEDED(hr)) {
6135             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
6136             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6137             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6138             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6139                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6140             ub_ok = SUCCEEDED(hr);
6141
6142             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
6143             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6144             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
6145             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6146
6147             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
6148             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6149             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
6150             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6151                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6152             ub_ok = (SUCCEEDED(hr) && ub_ok);
6153
6154             hr = IDirect3DDevice9_EndScene(device);
6155             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6156         }
6157
6158         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6159         if(i == 0) {
6160             color = getPixelColor(device, 480, 360);
6161             ok(color == 0x00ff0000,
6162                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
6163             color = getPixelColor(device, 160, 120);
6164             ok(color == 0x00ffffff,
6165                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6166             color = getPixelColor(device, 160, 360);
6167             ok(color == 0x000000ff || !ub_ok,
6168                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6169             color = getPixelColor(device, 480, 120);
6170             ok(color == 0x000000ff || !ub_ok,
6171                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6172         } else {
6173             color = getPixelColor(device, 480, 360);
6174             ok(color == 0x000000ff,
6175                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
6176             color = getPixelColor(device, 160, 120);
6177             ok(color == 0x00ffffff,
6178                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6179             color = getPixelColor(device, 160, 360);
6180             ok(color == 0x00ff0000 || !ub_ok,
6181                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6182             color = getPixelColor(device, 480, 120);
6183             ok(color == 0x00ff0000 || !ub_ok,
6184                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6185         }
6186     }
6187
6188     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6189     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6190     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
6191     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6192     IDirect3DVertexBuffer9_Release(vb2);
6193
6194     out:
6195     IDirect3DVertexBuffer9_Release(vb);
6196     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
6197     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
6198     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
6199     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
6200     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
6201     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
6202     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
6203 }
6204
6205 struct vertex_float16color {
6206     float x, y, z;
6207     DWORD c1, c2;
6208 };
6209
6210 static void test_vshader_float16(IDirect3DDevice9 *device)
6211 {
6212     HRESULT hr;
6213     DWORD color;
6214     void *data;
6215     static const D3DVERTEXELEMENT9 decl_elements[] = {
6216         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6217         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6218         D3DDECL_END()
6219     };
6220     IDirect3DVertexDeclaration9 *vdecl = NULL;
6221     IDirect3DVertexBuffer9 *buffer = NULL;
6222     IDirect3DVertexShader9 *shader;
6223     DWORD shader_code[] = {
6224         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
6225         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
6226         0x90e40001, 0x0000ffff
6227     };
6228     struct vertex_float16color quad[] = {
6229         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
6230         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
6231         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
6232         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
6233
6234         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
6235         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
6236         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
6237         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
6238
6239         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
6240         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
6241         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
6242         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
6243
6244         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
6245         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
6246         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
6247         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
6248     };
6249
6250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6252
6253     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
6254     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
6255     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
6256     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6257     IDirect3DDevice9_SetVertexShader(device, shader);
6258     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6259
6260     hr = IDirect3DDevice9_BeginScene(device);
6261     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6262     if(SUCCEEDED(hr)) {
6263         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
6264         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6265         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
6266         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6267         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
6268         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6269         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
6270         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6271         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
6272         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6273
6274         hr = IDirect3DDevice9_EndScene(device);
6275         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6276     }
6277     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6278     color = getPixelColor(device, 480, 360);
6279     ok(color == 0x00ff0000,
6280        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6281     color = getPixelColor(device, 160, 120);
6282     ok(color == 0x00000000,
6283        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6284     color = getPixelColor(device, 160, 360);
6285     ok(color == 0x0000ff00,
6286        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6287     color = getPixelColor(device, 480, 120);
6288     ok(color == 0x000000ff,
6289        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6290
6291     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6292     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6293
6294     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
6295                                              D3DPOOL_MANAGED, &buffer, NULL);
6296     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
6297     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
6298     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
6299     memcpy(data, quad, sizeof(quad));
6300     hr = IDirect3DVertexBuffer9_Unlock(buffer);
6301     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
6302     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
6303     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6304
6305     hr = IDirect3DDevice9_BeginScene(device);
6306     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6307     if(SUCCEEDED(hr)) {
6308             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
6309             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6310             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
6311             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6312             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
6313             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6314             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
6315             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6316
6317             hr = IDirect3DDevice9_EndScene(device);
6318             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6319     }
6320
6321     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6322     color = getPixelColor(device, 480, 360);
6323     ok(color == 0x00ff0000,
6324        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6325     color = getPixelColor(device, 160, 120);
6326     ok(color == 0x00000000,
6327        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6328     color = getPixelColor(device, 160, 360);
6329     ok(color == 0x0000ff00,
6330        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6331     color = getPixelColor(device, 480, 120);
6332     ok(color == 0x000000ff,
6333        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6334
6335     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6336     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6337     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6338     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6339     IDirect3DDevice9_SetVertexShader(device, NULL);
6340     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6341
6342     IDirect3DVertexDeclaration9_Release(vdecl);
6343     IDirect3DVertexShader9_Release(shader);
6344     IDirect3DVertexBuffer9_Release(buffer);
6345 }
6346
6347 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
6348 {
6349     D3DCAPS9 caps;
6350     IDirect3DTexture9 *texture;
6351     HRESULT hr;
6352     D3DLOCKED_RECT rect;
6353     unsigned int x, y;
6354     DWORD *dst, color;
6355     const float quad[] = {
6356         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
6357          1.0,   -1.0,   0.1,    1.2,   -0.2,
6358         -1.0,    1.0,   0.1,   -0.2,    1.2,
6359          1.0,    1.0,   0.1,    1.2,    1.2
6360     };
6361     memset(&caps, 0, sizeof(caps));
6362
6363     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6364     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6365     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6366         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
6367         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
6368            "Card has conditional NP2 support without power of two restriction set\n");
6369         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
6370         return;
6371     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6372         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
6373         return;
6374     }
6375
6376     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
6377     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6378
6379     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6380     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6381
6382     memset(&rect, 0, sizeof(rect));
6383     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
6384     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
6385     for(y = 0; y < 10; y++) {
6386         for(x = 0; x < 10; x++) {
6387             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
6388             if(x == 0 || x == 9 || y == 0 || y == 9) {
6389                 *dst = 0x00ff0000;
6390             } else {
6391                 *dst = 0x000000ff;
6392             }
6393         }
6394     }
6395     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6396     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
6397
6398     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6399     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6400     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
6401     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6402     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
6403     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6404     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6405     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6406
6407     hr = IDirect3DDevice9_BeginScene(device);
6408     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6409     if(SUCCEEDED(hr)) {
6410         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
6411         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6412
6413         hr = IDirect3DDevice9_EndScene(device);
6414         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6415     }
6416
6417     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6418
6419     color = getPixelColor(device,    1,  1);
6420     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
6421     color = getPixelColor(device, 639, 479);
6422     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
6423
6424     color = getPixelColor(device, 135, 101);
6425     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
6426     color = getPixelColor(device, 140, 101);
6427     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
6428     color = getPixelColor(device, 135, 105);
6429     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
6430     color = getPixelColor(device, 140, 105);
6431     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
6432
6433     color = getPixelColor(device, 135, 376);
6434     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
6435     color = getPixelColor(device, 140, 376);
6436     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
6437     color = getPixelColor(device, 135, 379);
6438     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
6439     color = getPixelColor(device, 140, 379);
6440     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
6441
6442     color = getPixelColor(device, 500, 101);
6443     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
6444     color = getPixelColor(device, 504, 101);
6445     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
6446     color = getPixelColor(device, 500, 105);
6447     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
6448     color = getPixelColor(device, 504, 105);
6449     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
6450
6451     color = getPixelColor(device, 500, 376);
6452     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
6453     color = getPixelColor(device, 504, 376);
6454     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
6455     color = getPixelColor(device, 500, 380);
6456     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
6457     color = getPixelColor(device, 504, 380);
6458     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
6459
6460     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6461     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6462     IDirect3DTexture9_Release(texture);
6463 }
6464
6465 static void vFace_register_test(IDirect3DDevice9 *device)
6466 {
6467     HRESULT hr;
6468     DWORD color;
6469     const DWORD shader_code[] = {
6470         0xffff0300,                                                             /* ps_3_0                     */
6471         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
6472         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
6473         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
6474         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
6475         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
6476         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
6477         0x0000ffff                                                              /* END                        */
6478     };
6479     IDirect3DPixelShader9 *shader;
6480     IDirect3DTexture9 *texture;
6481     IDirect3DSurface9 *surface, *backbuffer;
6482     const float quad[] = {
6483         -1.0,   -1.0,   0.1,
6484          1.0,   -1.0,   0.1,
6485         -1.0,    0.0,   0.1,
6486
6487          1.0,   -1.0,   0.1,
6488          1.0,    0.0,   0.1,
6489         -1.0,    0.0,   0.1,
6490
6491         -1.0,    0.0,   0.1,
6492         -1.0,    1.0,   0.1,
6493          1.0,    0.0,   0.1,
6494
6495          1.0,    0.0,   0.1,
6496         -1.0,    1.0,   0.1,
6497          1.0,    1.0,   0.1,
6498     };
6499     const float blit[] = {
6500          0.0,   -1.0,   0.1,    0.0,    0.0,
6501          1.0,   -1.0,   0.1,    1.0,    0.0,
6502          0.0,    1.0,   0.1,    0.0,    1.0,
6503          1.0,    1.0,   0.1,    1.0,    1.0,
6504     };
6505
6506     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6507     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
6508     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6509     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6510     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6511     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
6512     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6513     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6514     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6515     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6516     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6517     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
6518
6519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6521
6522     hr = IDirect3DDevice9_BeginScene(device);
6523     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6524     if(SUCCEEDED(hr)) {
6525         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
6526         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6527         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6528         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6529         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6530         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6531         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6532         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6533         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6535         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6536
6537         /* Blit the texture ontp the back buffer to make it visible */
6538         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6539         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
6540         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6541         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
6542         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6543         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6544         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6545         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6546         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6547         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6548
6549         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
6550         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6551
6552         hr = IDirect3DDevice9_EndScene(device);
6553         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6554     }
6555
6556     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6557     color = getPixelColor(device, 160, 360);
6558     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6559     color = getPixelColor(device, 160, 120);
6560     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6561     color = getPixelColor(device, 480, 360);
6562     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6563     color = getPixelColor(device, 480, 120);
6564     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6565
6566     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6567     IDirect3DDevice9_SetTexture(device, 0, NULL);
6568     IDirect3DPixelShader9_Release(shader);
6569     IDirect3DSurface9_Release(surface);
6570     IDirect3DSurface9_Release(backbuffer);
6571     IDirect3DTexture9_Release(texture);
6572 }
6573
6574 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
6575 {
6576     HRESULT hr;
6577     DWORD color;
6578     int i;
6579     D3DCAPS9 caps;
6580
6581     static const float quad[][7] = {
6582         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
6583         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
6584         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
6585         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
6586     };
6587
6588     static const D3DVERTEXELEMENT9 decl_elements[] = {
6589         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6590         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6591         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6592         D3DDECL_END()
6593     };
6594
6595     /* use assymetric matrix to test loading */
6596     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
6597
6598     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
6599     IDirect3DTexture9           *texture            = NULL;
6600
6601     memset(&caps, 0, sizeof(caps));
6602     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6603     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6604     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
6605         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
6606         return;
6607     } else {
6608         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
6609          * They report that it is not supported, but after that bump mapping works properly. So just test
6610          * if the format is generally supported, and check the BUMPENVMAP flag
6611          */
6612         IDirect3D9 *d3d9;
6613
6614         IDirect3DDevice9_GetDirect3D(device, &d3d9);
6615         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
6616                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
6617         IDirect3D9_Release(d3d9);
6618         if(FAILED(hr)) {
6619             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
6620             return;
6621         }
6622     }
6623
6624     /* Generate the textures */
6625     generate_bumpmap_textures(device);
6626
6627     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
6628     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6629     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
6630     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6631     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
6632     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6633     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
6634     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6635
6636     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
6637     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6638     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
6639     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6640     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
6641     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6642
6643     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6644     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6645     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6646     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6647     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
6648     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6649
6650     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
6651     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6652
6653     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6654     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
6655
6656     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
6657     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
6658
6659
6660     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
6661     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
6662     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
6663     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
6664
6665     hr = IDirect3DDevice9_BeginScene(device);
6666     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
6667
6668     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
6669     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
6670
6671     hr = IDirect3DDevice9_EndScene(device);
6672     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
6673
6674     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6675     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
6676
6677     color = getPixelColor(device, 320-32, 240);
6678     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6679     color = getPixelColor(device, 320+32, 240);
6680     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6681     color = getPixelColor(device, 320, 240-32);
6682     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6683     color = getPixelColor(device, 320, 240+32);
6684     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6685     color = getPixelColor(device, 320, 240);
6686     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6687     color = getPixelColor(device, 320+32, 240+32);
6688     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6689     color = getPixelColor(device, 320-32, 240+32);
6690     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6691     color = getPixelColor(device, 320+32, 240-32);
6692     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6693     color = getPixelColor(device, 320-32, 240-32);
6694     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6695
6696     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6697     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
6698     IDirect3DVertexDeclaration9_Release(vertex_declaration);
6699
6700     for(i = 0; i < 2; i++) {
6701         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
6702         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
6703         IDirect3DTexture9_Release(texture); /* For the GetTexture */
6704         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
6705         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
6706         IDirect3DTexture9_Release(texture); /* To destroy it */
6707     }
6708
6709     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6710     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6711     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
6712     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6713
6714 }
6715
6716 static void stencil_cull_test(IDirect3DDevice9 *device) {
6717     HRESULT hr;
6718     IDirect3DSurface9 *depthstencil = NULL;
6719     D3DSURFACE_DESC desc;
6720     float quad1[] = {
6721         -1.0,   -1.0,   0.1,
6722          0.0,   -1.0,   0.1,
6723         -1.0,    0.0,   0.1,
6724          0.0,    0.0,   0.1,
6725     };
6726     float quad2[] = {
6727          0.0,   -1.0,   0.1,
6728          1.0,   -1.0,   0.1,
6729          0.0,    0.0,   0.1,
6730          1.0,    0.0,   0.1,
6731     };
6732     float quad3[] = {
6733         0.0,    0.0,   0.1,
6734         1.0,    0.0,   0.1,
6735         0.0,    1.0,   0.1,
6736         1.0,    1.0,   0.1,
6737     };
6738     float quad4[] = {
6739         -1.0,    0.0,   0.1,
6740          0.0,    0.0,   0.1,
6741         -1.0,    1.0,   0.1,
6742          0.0,    1.0,   0.1,
6743     };
6744     struct vertex painter[] = {
6745        {-1.0,   -1.0,   0.0,    0x00000000},
6746        { 1.0,   -1.0,   0.0,    0x00000000},
6747        {-1.0,    1.0,   0.0,    0x00000000},
6748        { 1.0,    1.0,   0.0,    0x00000000},
6749     };
6750     WORD indices_cw[]  = {0, 1, 3};
6751     WORD indices_ccw[] = {0, 2, 3};
6752     unsigned int i;
6753     DWORD color;
6754
6755     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
6756     if(depthstencil == NULL) {
6757         skip("No depth stencil buffer\n");
6758         return;
6759     }
6760     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
6761     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
6762     IDirect3DSurface9_Release(depthstencil);
6763     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
6764         skip("No 4 or 8 bit stencil surface\n");
6765         return;
6766     }
6767
6768     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
6769     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6770     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6771
6772     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
6773     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6774     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
6775     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6776     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
6777     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6778     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
6779     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6780
6781     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
6782     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6783     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
6784     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6785     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
6786     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6787
6788     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
6789     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6790     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
6791     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6792
6793     /* First pass: Fill the stencil buffer with some values... */
6794     hr = IDirect3DDevice9_BeginScene(device);
6795     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6796     if(SUCCEEDED(hr))
6797     {
6798         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
6799         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6800         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6801                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
6802         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6803                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
6804
6805         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
6806         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6807         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
6808         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6809         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6810                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
6811         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6812                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
6813
6814         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
6815         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6816         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6817                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
6818         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6819                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
6820
6821         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
6822         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6823         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6824                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
6825         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6826                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
6827
6828         hr = IDirect3DDevice9_EndScene(device);
6829         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6830     }
6831
6832     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6833     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
6834     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6835     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
6836     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6837     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
6838     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6839     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
6840     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
6842     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
6844     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6845
6846     /* 2nd pass: Make the stencil values visible */
6847     hr = IDirect3DDevice9_BeginScene(device);
6848     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6849     if(SUCCEEDED(hr))
6850     {
6851         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6852         for(i = 0; i < 16; i++) {
6853             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
6854             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6855
6856             painter[0].diffuse = (i * 16); /* Creates shades of blue */
6857             painter[1].diffuse = (i * 16);
6858             painter[2].diffuse = (i * 16);
6859             painter[3].diffuse = (i * 16);
6860             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
6861             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6862         }
6863         hr = IDirect3DDevice9_EndScene(device);
6864         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6865     }
6866
6867     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6868     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6869
6870     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
6871     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6872
6873     color = getPixelColor(device, 160, 420);
6874     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
6875     color = getPixelColor(device, 160, 300);
6876     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
6877
6878     color = getPixelColor(device, 480, 420);
6879     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
6880     color = getPixelColor(device, 480, 300);
6881     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
6882
6883     color = getPixelColor(device, 160, 180);
6884     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
6885     color = getPixelColor(device, 160, 60);
6886     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
6887
6888     color = getPixelColor(device, 480, 180);
6889     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
6890     color = getPixelColor(device, 480, 60);
6891     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
6892 }
6893
6894 static void vpos_register_test(IDirect3DDevice9 *device)
6895 {
6896     HRESULT hr;
6897     DWORD color;
6898     const DWORD shader_code[] = {
6899     0xffff0300,                                                             /* ps_3_0                     */
6900     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
6901     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
6902     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
6903     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
6904     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
6905     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
6906     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
6907     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
6908     0x0000ffff                                                              /* end                        */
6909     };
6910     const DWORD shader_frac_code[] = {
6911     0xffff0300,                                                             /* ps_3_0                     */
6912     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6913     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
6914     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
6915     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
6916     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
6917     0x0000ffff                                                              /* end                        */
6918     };
6919     IDirect3DPixelShader9 *shader, *shader_frac;
6920     IDirect3DSurface9 *surface = NULL, *backbuffer;
6921     const float quad[] = {
6922         -1.0,   -1.0,   0.1,    0.0,    0.0,
6923          1.0,   -1.0,   0.1,    1.0,    0.0,
6924         -1.0,    1.0,   0.1,    0.0,    1.0,
6925          1.0,    1.0,   0.1,    1.0,    1.0,
6926     };
6927     D3DLOCKED_RECT lr;
6928     float constant[4] = {1.0, 0.0, 320, 240};
6929     DWORD *pos;
6930
6931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6933     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6934     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
6935     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
6936     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
6937     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6938     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6939     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6940     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6941     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6942     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
6943
6944     hr = IDirect3DDevice9_BeginScene(device);
6945     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6946     if(SUCCEEDED(hr)) {
6947         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
6948         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
6949         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
6950         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6951         hr = IDirect3DDevice9_EndScene(device);
6952         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6953     }
6954
6955     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6956     /* This has to be pixel exact */
6957     color = getPixelColor(device, 319, 239);
6958     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
6959     color = getPixelColor(device, 320, 239);
6960     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
6961     color = getPixelColor(device, 319, 240);
6962     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
6963     color = getPixelColor(device, 320, 240);
6964     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
6965
6966     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
6967                                              &surface, NULL);
6968     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
6969     hr = IDirect3DDevice9_BeginScene(device);
6970     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6971     if(SUCCEEDED(hr)) {
6972         constant[2] = 16; constant[3] = 16;
6973         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
6974         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
6975         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6976         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6977         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
6978         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6979         hr = IDirect3DDevice9_EndScene(device);
6980         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6981     }
6982     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
6983     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
6984
6985     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
6986     color = *pos & 0x00ffffff;
6987     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
6988     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
6989     color = *pos & 0x00ffffff;
6990     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
6991     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
6992     color = *pos & 0x00ffffff;
6993     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
6994     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
6995     color = *pos & 0x00ffffff;
6996     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
6997
6998     hr = IDirect3DSurface9_UnlockRect(surface);
6999     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
7000
7001     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
7002      * have full control over the multisampling setting inside this test
7003      */
7004     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
7005     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7006     hr = IDirect3DDevice9_BeginScene(device);
7007     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7008     if(SUCCEEDED(hr)) {
7009         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7010         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7011         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7012         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7013         hr = IDirect3DDevice9_EndScene(device);
7014         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7015     }
7016     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7017     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7018
7019     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
7020     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
7021
7022     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
7023     color = *pos & 0x00ffffff;
7024     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
7025
7026     hr = IDirect3DSurface9_UnlockRect(surface);
7027     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
7028
7029     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7030     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7031     IDirect3DPixelShader9_Release(shader);
7032     IDirect3DPixelShader9_Release(shader_frac);
7033     if(surface) IDirect3DSurface9_Release(surface);
7034     IDirect3DSurface9_Release(backbuffer);
7035 }
7036
7037 static void pointsize_test(IDirect3DDevice9 *device)
7038 {
7039     HRESULT hr;
7040     D3DCAPS9 caps;
7041     D3DMATRIX matrix;
7042     D3DMATRIX identity;
7043     float ptsize, ptsize_orig;
7044     DWORD color;
7045
7046     const float vertices[] = {
7047         64,     64,     0.1,
7048         128,    64,     0.1,
7049         192,    64,     0.1,
7050         256,    64,     0.1,
7051         320,    64,     0.1,
7052         384,    64,     0.1
7053     };
7054
7055     /* 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 */
7056     matrix.m[0][0] = 2.0/640.0; matrix.m[1][0] = 0.0;       matrix.m[2][0] = 0.0;   matrix.m[3][0] =-1.0;
7057     matrix.m[0][1] = 0.0;       matrix.m[1][1] =-2.0/480.0; matrix.m[2][1] = 0.0;   matrix.m[3][1] = 1.0;
7058     matrix.m[0][2] = 0.0;       matrix.m[1][2] = 0.0;       matrix.m[2][2] = 1.0;   matrix.m[3][2] = 0.0;
7059     matrix.m[0][3] = 0.0;       matrix.m[1][3] = 0.0;       matrix.m[2][3] = 0.0;   matrix.m[3][3] = 1.0;
7060
7061     identity.m[0][0] = 1.0;     identity.m[1][0] = 0.0;     identity.m[2][0] = 0.0; identity.m[3][0] = 0.0;
7062     identity.m[0][1] = 0.0;     identity.m[1][1] = 1.0;     identity.m[2][1] = 0.0; identity.m[3][1] = 0.0;
7063     identity.m[0][2] = 0.0;     identity.m[1][2] = 0.0;     identity.m[2][2] = 1.0; identity.m[3][2] = 0.0;
7064     identity.m[0][3] = 0.0;     identity.m[1][3] = 0.0;     identity.m[2][3] = 0.0; identity.m[3][3] = 1.0;
7065
7066     memset(&caps, 0, sizeof(caps));
7067     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7068     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7069     if(caps.MaxPointSize < 32.0) {
7070         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
7071         return;
7072     }
7073
7074     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
7075     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7076     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
7077     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
7078     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7079     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7080     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
7081     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
7082
7083     hr = IDirect3DDevice9_BeginScene(device);
7084     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7085     if(SUCCEEDED(hr)) {
7086         ptsize = 16.0;
7087         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7088         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7089         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7090         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7091
7092         ptsize = 32.0;
7093         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7094         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
7096         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7097
7098         ptsize = 31.5;
7099         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7100         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7101         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
7102         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7103
7104         if(caps.MaxPointSize >= 64.0) {
7105             ptsize = 64.0;
7106             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7107             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7108             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
7109             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7110
7111             ptsize = 63.75;
7112             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7113             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7114             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
7115             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7116         }
7117
7118         ptsize = 1.0;
7119         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7120         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
7122         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7123
7124         hr = IDirect3DDevice9_EndScene(device);
7125         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7126     }
7127     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7128     color = getPixelColor(device, 64-9, 64-9);
7129     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
7130     color = getPixelColor(device, 64-8, 64-8);
7131     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
7132     color = getPixelColor(device, 64-7, 64-7);
7133     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
7134     color = getPixelColor(device, 64+7, 64+7);
7135     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
7136     color = getPixelColor(device, 64+8, 64+8);
7137     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
7138     color = getPixelColor(device, 64+9, 64+9);
7139     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
7140
7141     color = getPixelColor(device, 128-17, 64-17);
7142     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
7143     color = getPixelColor(device, 128-16, 64-16);
7144     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
7145     color = getPixelColor(device, 128-15, 64-15);
7146     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
7147     color = getPixelColor(device, 128+15, 64+15);
7148     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
7149     color = getPixelColor(device, 128+16, 64+16);
7150     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
7151     color = getPixelColor(device, 128+17, 64+17);
7152     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
7153
7154     color = getPixelColor(device, 192-17, 64-17);
7155     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
7156     color = getPixelColor(device, 192-16, 64-16);
7157     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
7158     color = getPixelColor(device, 192-15, 64-15);
7159     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
7160     color = getPixelColor(device, 192+15, 64+15);
7161     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
7162     color = getPixelColor(device, 192+16, 64+16);
7163     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
7164     color = getPixelColor(device, 192+17, 64+17);
7165     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
7166
7167     if(caps.MaxPointSize >= 64.0) {
7168         color = getPixelColor(device, 256-33, 64-33);
7169         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
7170         color = getPixelColor(device, 256-32, 64-32);
7171         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
7172         color = getPixelColor(device, 256-31, 64-31);
7173         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
7174         color = getPixelColor(device, 256+31, 64+31);
7175         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
7176         color = getPixelColor(device, 256+32, 64+32);
7177         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
7178         color = getPixelColor(device, 256+33, 64+33);
7179         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
7180
7181         color = getPixelColor(device, 384-33, 64-33);
7182         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
7183         color = getPixelColor(device, 384-32, 64-32);
7184         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
7185         color = getPixelColor(device, 384-31, 64-31);
7186         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
7187         color = getPixelColor(device, 384+31, 64+31);
7188         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
7189         color = getPixelColor(device, 384+32, 64+32);
7190         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
7191         color = getPixelColor(device, 384+33, 64+33);
7192         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
7193     }
7194
7195     color = getPixelColor(device, 320-1, 64-1);
7196     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
7197     color = getPixelColor(device, 320-0, 64-0);
7198     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
7199     color = getPixelColor(device, 320+1, 64+1);
7200     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
7201
7202     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
7203     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
7204     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
7205     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
7206 }
7207
7208 START_TEST(visual)
7209 {
7210     IDirect3DDevice9 *device_ptr;
7211     D3DCAPS9 caps;
7212     HRESULT hr;
7213     DWORD color;
7214
7215     d3d9_handle = LoadLibraryA("d3d9.dll");
7216     if (!d3d9_handle)
7217     {
7218         skip("Could not load d3d9.dll\n");
7219         return;
7220     }
7221
7222     device_ptr = init_d3d9();
7223     if (!device_ptr)
7224     {
7225         skip("Creating the device failed\n");
7226         return;
7227     }
7228
7229     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
7230
7231     /* Check for the reliability of the returned data */
7232     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
7233     if(FAILED(hr))
7234     {
7235         trace("Clear failed, can't assure correctness of the test results, skipping\n");
7236         goto cleanup;
7237     }
7238     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
7239
7240     color = getPixelColor(device_ptr, 1, 1);
7241     if(color !=0x00ff0000)
7242     {
7243         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
7244         goto cleanup;
7245     }
7246
7247     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
7248     if(FAILED(hr))
7249     {
7250         trace("Clear failed, can't assure correctness of the test results, skipping\n");
7251         goto cleanup;
7252     }
7253     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
7254
7255     color = getPixelColor(device_ptr, 639, 479);
7256     if(color != 0x0000ddee)
7257     {
7258         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
7259         goto cleanup;
7260     }
7261
7262     /* Now execute the real tests */
7263     lighting_test(device_ptr);
7264     clear_test(device_ptr);
7265     fog_test(device_ptr);
7266     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
7267     {
7268         test_cube_wrap(device_ptr);
7269     } else {
7270         skip("No cube texture support\n");
7271     }
7272     z_range_test(device_ptr);
7273     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
7274     {
7275         maxmip_test(device_ptr);
7276     }
7277     else
7278     {
7279         skip("No mipmap support\n");
7280     }
7281     offscreen_test(device_ptr);
7282     alpha_test(device_ptr);
7283     release_buffer_test(device_ptr);
7284     float_texture_test(device_ptr);
7285     g16r16_texture_test(device_ptr);
7286     texture_transform_flags_test(device_ptr);
7287     autogen_mipmap_test(device_ptr);
7288     fixed_function_decl_test(device_ptr);
7289     conditional_np2_repeat_test(device_ptr);
7290     fixed_function_bumpmap_test(device_ptr);
7291     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
7292         stencil_cull_test(device_ptr);
7293     } else {
7294         skip("No two sided stencil support\n");
7295     }
7296     pointsize_test(device_ptr);
7297
7298     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
7299     {
7300         test_constant_clamp_vs(device_ptr);
7301         test_compare_instructions(device_ptr);
7302     }
7303     else skip("No vs_1_1 support\n");
7304
7305     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
7306     {
7307         test_mova(device_ptr);
7308         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
7309             test_vshader_input(device_ptr);
7310             test_vshader_float16(device_ptr);
7311         } else {
7312             skip("No vs_3_0 support\n");
7313         }
7314     }
7315     else skip("No vs_2_0 support\n");
7316
7317     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
7318     {
7319         fog_with_shader_test(device_ptr);
7320         fog_srgbwrite_test(device_ptr);
7321     }
7322     else skip("No vs_1_1 and ps_1_1 support\n");
7323
7324     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
7325     {
7326         texbem_test(device_ptr);
7327         texdepth_test(device_ptr);
7328         texkill_test(device_ptr);
7329         x8l8v8u8_test(device_ptr);
7330         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
7331             constant_clamp_ps_test(device_ptr);
7332             cnd_test(device_ptr);
7333             if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
7334                 nested_loop_test(device_ptr);
7335                 fixed_function_varying_test(device_ptr);
7336                 vFace_register_test(device_ptr);
7337                 vpos_register_test(device_ptr);
7338                 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
7339                     vshader_version_varying_test(device_ptr);
7340                     pshader_version_varying_test(device_ptr);
7341                 } else {
7342                     skip("No vs_3_0 support\n");
7343                 }
7344             } else {
7345                 skip("No ps_3_0 support\n");
7346             }
7347         }
7348     }
7349     else skip("No ps_1_1 support\n");
7350
7351 cleanup:
7352     if(device_ptr) {
7353         ULONG ref;
7354
7355         D3DPRESENT_PARAMETERS present_parameters;
7356         IDirect3DSwapChain9 *swapchain;
7357         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
7358         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
7359         IDirect3DSwapChain9_Release(swapchain);
7360         ref = IDirect3DDevice9_Release(device_ptr);
7361         DestroyWindow(present_parameters.hDeviceWindow);
7362         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
7363     }
7364 }