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