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