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