wintrust: Add a helper function to initialize chain creation parameters.
[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.x1 = 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     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2571     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2573     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2576 }
2577
2578 static void texkill_test(IDirect3DDevice9 *device)
2579 {
2580     IDirect3DPixelShader9 *shader;
2581     HRESULT hr;
2582     DWORD color;
2583
2584     const float vertex[] = {
2585     /*                          bottom  top    right    left */
2586         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
2587          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
2588         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
2589          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
2590     };
2591
2592     DWORD shader_code_11[] = {
2593     0xffff0101,                                                             /* ps_1_1                     */
2594     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
2595     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
2596     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
2597     0x0000ffff                                                              /* end                        */
2598     };
2599     DWORD shader_code_20[] = {
2600     0xffff0200,                                                             /* ps_2_0                     */
2601     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
2602     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
2603     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
2604     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
2605     0x0000ffff                                                              /* end                        */
2606     };
2607
2608     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
2609     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2610     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
2611     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2612
2613     hr = IDirect3DDevice9_SetPixelShader(device, shader);
2614     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
2615     hr = IDirect3DDevice9_BeginScene(device);
2616     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2617     if(SUCCEEDED(hr))
2618     {
2619         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
2620         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
2621         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
2622         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2623         hr = IDirect3DDevice9_EndScene(device);
2624         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2625     }
2626     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2627     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2628     color = getPixelColor(device, 63, 46);
2629     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
2630     color = getPixelColor(device, 66, 46);
2631     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
2632     color = getPixelColor(device, 63, 49);
2633     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
2634     color = getPixelColor(device, 66, 49);
2635     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
2636
2637     color = getPixelColor(device, 578, 46);
2638     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
2639     color = getPixelColor(device, 575, 46);
2640     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
2641     color = getPixelColor(device, 578, 49);
2642     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
2643     color = getPixelColor(device, 575, 49);
2644     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
2645
2646     color = getPixelColor(device, 63, 430);
2647     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
2648     color = getPixelColor(device, 63, 433);
2649     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
2650     color = getPixelColor(device, 66, 433);
2651     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
2652     color = getPixelColor(device, 66, 430);
2653     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
2654
2655     color = getPixelColor(device, 578, 430);
2656     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
2657     color = getPixelColor(device, 578, 433);
2658     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
2659     color = getPixelColor(device, 575, 433);
2660     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
2661     color = getPixelColor(device, 575, 430);
2662     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
2663
2664     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2665     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
2666     IDirect3DPixelShader9_Release(shader);
2667
2668     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2669     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2670     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
2671     if(FAILED(hr)) {
2672         skip("Failed to create 2.0 test shader, most likely not supported\n");
2673         return;
2674     }
2675
2676     hr = IDirect3DDevice9_SetPixelShader(device, shader);
2677     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
2678     hr = IDirect3DDevice9_BeginScene(device);
2679     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2680     if(SUCCEEDED(hr))
2681     {
2682         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
2683         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2684         hr = IDirect3DDevice9_EndScene(device);
2685         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2686     }
2687     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2688
2689     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2690     color = getPixelColor(device, 63, 46);
2691     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
2692     color = getPixelColor(device, 66, 46);
2693     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
2694     color = getPixelColor(device, 63, 49);
2695     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
2696     color = getPixelColor(device, 66, 49);
2697     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
2698
2699     color = getPixelColor(device, 578, 46);
2700     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
2701     color = getPixelColor(device, 575, 46);
2702     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
2703     color = getPixelColor(device, 578, 49);
2704     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
2705     color = getPixelColor(device, 575, 49);
2706     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
2707
2708     color = getPixelColor(device, 63, 430);
2709     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
2710     color = getPixelColor(device, 63, 433);
2711     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
2712     color = getPixelColor(device, 66, 433);
2713     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
2714     color = getPixelColor(device, 66, 430);
2715     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
2716
2717     color = getPixelColor(device, 578, 430);
2718     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
2719     color = getPixelColor(device, 578, 433);
2720     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
2721     color = getPixelColor(device, 575, 433);
2722     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
2723     color = getPixelColor(device, 575, 430);
2724     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
2725 }
2726
2727 static void x8l8v8u8_test(IDirect3DDevice9 *device)
2728 {
2729     IDirect3D9 *d3d9;
2730     HRESULT hr;
2731     IDirect3DTexture9 *texture;
2732     IDirect3DPixelShader9 *shader;
2733     IDirect3DPixelShader9 *shader2;
2734     D3DLOCKED_RECT lr;
2735     DWORD color;
2736     DWORD shader_code[] = {
2737         0xffff0101,                             /* ps_1_1       */
2738         0x00000042, 0xb00f0000,                 /* tex t0       */
2739         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
2740         0x0000ffff                              /* end          */
2741     };
2742     DWORD shader_code2[] = {
2743         0xffff0101,                             /* ps_1_1       */
2744         0x00000042, 0xb00f0000,                 /* tex t0       */
2745         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
2746         0x0000ffff                              /* end          */
2747     };
2748
2749     float quad[] = {
2750        -1.0,   -1.0,   0.1,     0.5,    0.5,
2751         1.0,   -1.0,   0.1,     0.5,    0.5,
2752        -1.0,    1.0,   0.1,     0.5,    0.5,
2753         1.0,    1.0,   0.1,     0.5,    0.5,
2754     };
2755
2756     memset(&lr, 0, sizeof(lr));
2757     IDirect3DDevice9_GetDirect3D(device, &d3d9);
2758     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2759                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
2760     IDirect3D9_Release(d3d9);
2761     if(FAILED(hr)) {
2762         skip("No D3DFMT_X8L8V8U8 support\n");
2763     };
2764
2765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2766     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2767
2768     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
2769     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
2770     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2771     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
2772     *((DWORD *) lr.pBits) = 0x11ca3141;
2773     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2774     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
2775
2776     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
2777     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
2778     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
2779     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
2780
2781     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2782     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
2783     hr = IDirect3DDevice9_SetPixelShader(device, shader);
2784     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2785     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2786     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
2787
2788     hr = IDirect3DDevice9_BeginScene(device);
2789     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
2790     if(SUCCEEDED(hr))
2791     {
2792         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2793         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2794
2795         hr = IDirect3DDevice9_EndScene(device);
2796         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
2797     }
2798     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2799     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2800     color = getPixelColor(device, 578, 430);
2801     ok(color == 0x008262ca, "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
2802
2803     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
2804     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2805     hr = IDirect3DDevice9_BeginScene(device);
2806     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
2807     if(SUCCEEDED(hr))
2808     {
2809         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2810         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2811
2812         hr = IDirect3DDevice9_EndScene(device);
2813         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
2814     }
2815     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2816     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2817     color = getPixelColor(device, 578, 430);
2818     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
2819
2820     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2821     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2822     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2823     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
2824     IDirect3DPixelShader9_Release(shader);
2825     IDirect3DPixelShader9_Release(shader2);
2826     IDirect3DTexture9_Release(texture);
2827 }
2828
2829 static void autogen_mipmap_test(IDirect3DDevice9 *device)
2830 {
2831     HRESULT hr;
2832     IDirect3D9 *d3d;
2833     IDirect3DTexture9 *texture = NULL;
2834     IDirect3DSurface9 *surface;
2835     DWORD color;
2836     const RECT r1 = {256, 256, 512, 512};
2837     const RECT r2 = {512, 256, 768, 512};
2838     const RECT r3 = {256, 512, 512, 768};
2839     const RECT r4 = {512, 512, 768, 768};
2840     unsigned int x, y;
2841     D3DLOCKED_RECT lr;
2842     memset(&lr, 0, sizeof(lr));
2843
2844     IDirect3DDevice9_GetDirect3D(device, &d3d);
2845     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2846        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
2847         skip("No autogenmipmap support\n");
2848         IDirect3D9_Release(d3d);
2849         return;
2850     }
2851     IDirect3D9_Release(d3d);
2852
2853     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2854     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2855
2856     /* Make the mipmap big, so that a smaller mipmap is used
2857      */
2858     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
2859                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
2860     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
2861
2862     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2863     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
2864     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
2865     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
2866     for(y = 0; y < 1024; y++) {
2867         for(x = 0; x < 1024; x++) {
2868             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
2869             POINT pt;
2870
2871             pt.x = x;
2872             pt.y = y;
2873             if(PtInRect(&r1, pt)) {
2874                 *dst = 0xffff0000;
2875             } else if(PtInRect(&r2, pt)) {
2876                 *dst = 0xff00ff00;
2877             } else if(PtInRect(&r3, pt)) {
2878                 *dst = 0xff0000ff;
2879             } else if(PtInRect(&r4, pt)) {
2880                 *dst = 0xff000000;
2881             } else {
2882                 *dst = 0xffffffff;
2883             }
2884         }
2885     }
2886     hr = IDirect3DSurface9_UnlockRect(surface);
2887     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
2888     IDirect3DSurface9_Release(surface);
2889
2890     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2891     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2892     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2893     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2894
2895     hr = IDirect3DDevice9_BeginScene(device);
2896     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2897     if(SUCCEEDED(hr)) {
2898         const float quad[] =  {
2899            -0.5,   -0.5,    0.1,    0.0,    0.0,
2900            -0.5,    0.5,    0.1,    0.0,    1.0,
2901             0.5,   -0.5,    0.1,    1.0,    0.0,
2902             0.5,    0.5,    0.1,    1.0,    1.0
2903         };
2904
2905         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2906         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
2907         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2908         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2909         hr = IDirect3DDevice9_EndScene(device);
2910         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2911     }
2912     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2913     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2914     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2915     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2916     IDirect3DTexture9_Release(texture);
2917
2918     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2919     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2920     color = getPixelColor(device, 200, 200);
2921     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
2922     color = getPixelColor(device, 280, 200);
2923     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
2924     color = getPixelColor(device, 360, 200);
2925     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
2926     color = getPixelColor(device, 440, 200);
2927     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
2928     color = getPixelColor(device, 200, 270);
2929     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
2930     color = getPixelColor(device, 280, 270);
2931     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
2932     color = getPixelColor(device, 360, 270);
2933     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
2934     color = getPixelColor(device, 440, 270);
2935     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
2936 }
2937
2938 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
2939 {
2940     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
2941     IDirect3DVertexDeclaration9 *decl;
2942     HRESULT hr;
2943     DWORD color;
2944     DWORD shader_code_11[] =  {
2945         0xfffe0101,                                         /* vs_1_1           */
2946         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
2947         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
2948         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
2949         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
2950         0x0000ffff                                          /* end              */
2951     };
2952     DWORD shader_code_11_2[] =  {
2953         0xfffe0101,                                         /* vs_1_1           */
2954         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
2955         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
2956         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
2957         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
2958         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
2959         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
2960         0x0000ffff                                          /* end              */
2961     };
2962     DWORD shader_code_20[] =  {
2963         0xfffe0200,                                         /* vs_2_0           */
2964         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
2965         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
2966         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
2967         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
2968         0x0000ffff                                          /* end              */
2969     };
2970     DWORD shader_code_20_2[] =  {
2971         0xfffe0200,                                         /* vs_2_0           */
2972         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
2973         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
2974         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
2975         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
2976         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
2977         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
2978         0x0000ffff                                          /* end              */
2979     };
2980     static const D3DVERTEXELEMENT9 decl_elements[] = {
2981         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2982         D3DDECL_END()
2983     };
2984     float quad1[] = {
2985         -1.0,   -1.0,   0.1,
2986          0.0,   -1.0,   0.1,
2987         -1.0,    0.0,   0.1,
2988          0.0,    0.0,   0.1
2989     };
2990     float quad2[] = {
2991          0.0,   -1.0,   0.1,
2992          1.0,   -1.0,   0.1,
2993          0.0,    0.0,   0.1,
2994          1.0,    0.0,   0.1
2995     };
2996     float quad3[] = {
2997          0.0,    0.0,   0.1,
2998          1.0,    0.0,   0.1,
2999          0.0,    1.0,   0.1,
3000          1.0,    1.0,   0.1
3001     };
3002     float quad4[] = {
3003         -1.0,    0.0,   0.1,
3004          0.0,    0.0,   0.1,
3005         -1.0,    1.0,   0.1,
3006          0.0,    1.0,   0.1
3007     };
3008     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3009     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3010
3011     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3012     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3013
3014     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
3015     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3016     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
3017     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3018     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
3019     if(FAILED(hr)) shader_20 = NULL;
3020     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
3021     if(FAILED(hr)) shader_20_2 = NULL;
3022     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3023     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3024
3025     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
3026     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3027     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
3028     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3029     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3030     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3031
3032     hr = IDirect3DDevice9_BeginScene(device);
3033     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3034     if(SUCCEEDED(hr))
3035     {
3036         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
3037         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3038         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3039         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3040
3041         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
3042         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3043         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3044         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3045
3046         if(shader_20) {
3047             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
3048             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3049             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3050             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3051         }
3052
3053         if(shader_20_2) {
3054             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
3055             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3056             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3057             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3058         }
3059
3060         hr = IDirect3DDevice9_EndScene(device);
3061         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3062     }
3063     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3064     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3065
3066     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3067     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3068     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3069     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3070
3071     color = getPixelColor(device, 160, 360);
3072     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3073        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
3074     color = getPixelColor(device, 480, 360);
3075     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3076        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
3077     if(shader_20) {
3078         color = getPixelColor(device, 160, 120);
3079         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3080            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
3081     }
3082     if(shader_20_2) {
3083         color = getPixelColor(device, 480, 120);
3084         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3085            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3086     }
3087
3088     IDirect3DVertexDeclaration9_Release(decl);
3089     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
3090     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
3091     IDirect3DVertexShader9_Release(shader_11_2);
3092     IDirect3DVertexShader9_Release(shader_11);
3093 }
3094
3095 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
3096 {
3097     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
3098     HRESULT hr;
3099     DWORD color;
3100     DWORD shader_code_11[] =  {
3101         0xffff0101,                                         /* ps_1_1           */
3102         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3103         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3104         0x0000ffff                                          /* end              */
3105     };
3106     DWORD shader_code_12[] =  {
3107         0xffff0102,                                         /* ps_1_2           */
3108         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3109         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3110         0x0000ffff                                          /* end              */
3111     };
3112     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
3113      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
3114      * During development of this test, 1.3 shaders were verified too
3115      */
3116     DWORD shader_code_14[] =  {
3117         0xffff0104,                                         /* ps_1_4           */
3118         /* Try to make one constant local. It gets clamped too, although the binary contains
3119          * the bigger numbers
3120          */
3121         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
3122         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3123         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3124         0x0000ffff                                          /* end              */
3125     };
3126     DWORD shader_code_20[] =  {
3127         0xffff0200,                                         /* ps_2_0           */
3128         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3129         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3130         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
3131         0x0000ffff                                          /* end              */
3132     };
3133     float quad1[] = {
3134         -1.0,   -1.0,   0.1,
3135          0.0,   -1.0,   0.1,
3136         -1.0,    0.0,   0.1,
3137          0.0,    0.0,   0.1
3138     };
3139     float quad2[] = {
3140          0.0,   -1.0,   0.1,
3141          1.0,   -1.0,   0.1,
3142          0.0,    0.0,   0.1,
3143          1.0,    0.0,   0.1
3144     };
3145     float quad3[] = {
3146          0.0,    0.0,   0.1,
3147          1.0,    0.0,   0.1,
3148          0.0,    1.0,   0.1,
3149          1.0,    1.0,   0.1
3150     };
3151     float quad4[] = {
3152         -1.0,    0.0,   0.1,
3153          0.0,    0.0,   0.1,
3154         -1.0,    1.0,   0.1,
3155          0.0,    1.0,   0.1
3156     };
3157     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3158     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3159
3160     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3161     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3162
3163     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3164     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3165     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3166     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3167     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3168     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3169     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
3170     if(FAILED(hr)) shader_20 = NULL;
3171
3172     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3173     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3174     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3175     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3176     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3177     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3178
3179     hr = IDirect3DDevice9_BeginScene(device);
3180     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3181     if(SUCCEEDED(hr))
3182     {
3183         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3184         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3186         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3187
3188         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3189         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3191         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3192
3193         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3194         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3195         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3196         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3197
3198         if(shader_20) {
3199             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
3200             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3201             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3202             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3203         }
3204
3205         hr = IDirect3DDevice9_EndScene(device);
3206         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3207     }
3208     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3209     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3210
3211     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3212     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3213
3214     color = getPixelColor(device, 160, 360);
3215     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3216        "quad 1 has color %08x, expected 0x00808000\n", color);
3217     color = getPixelColor(device, 480, 360);
3218     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3219        "quad 2 has color %08x, expected 0x00808000\n", color);
3220     color = getPixelColor(device, 480, 120);
3221     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3222        "quad 3 has color %08x, expected 0x00808000\n", color);
3223     if(shader_20) {
3224         color = getPixelColor(device, 160, 120);
3225         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3226            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3227     }
3228
3229     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
3230     IDirect3DPixelShader9_Release(shader_14);
3231     IDirect3DPixelShader9_Release(shader_12);
3232     IDirect3DPixelShader9_Release(shader_11);
3233 }
3234
3235 static void cnd_test(IDirect3DDevice9 *device)
3236 {
3237     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
3238     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
3239     HRESULT hr;
3240     DWORD color;
3241     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
3242      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
3243      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
3244      */
3245     DWORD shader_code_11[] =  {
3246         0xffff0101,                                                                 /* ps_1_1               */
3247         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3248         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3249         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
3250         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3251         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3252         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3253         0x0000ffff                                                                  /* end                  */
3254     };
3255     DWORD shader_code_12[] =  {
3256         0xffff0102,                                                                 /* ps_1_2               */
3257         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3258         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3259         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3260         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3261         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3262         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3263         0x0000ffff                                                                  /* end                  */
3264     };
3265     DWORD shader_code_13[] =  {
3266         0xffff0103,                                                                 /* ps_1_3               */
3267         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3268         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3269         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3270         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
3271         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3272         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3273         0x0000ffff                                                                  /* end                  */
3274     };
3275     DWORD shader_code_14[] =  {
3276         0xffff0104,                                                                 /* ps_1_3               */
3277         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
3278         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
3279         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
3280         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
3281         0x0000ffff                                                                  /* end                  */
3282     };
3283
3284     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
3285      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
3286      * set by the compiler, it was added manually after compilation. It isn't always allowed,
3287      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
3288      * native CreatePixelShader returns an error.
3289      *
3290      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
3291      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
3292      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
3293      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
3294      */
3295     DWORD shader_code_11_coissue[] =  {
3296         0xffff0101,                                                             /* ps_1_1                   */
3297         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3298         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3299         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3300         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3301         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3302         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3303         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3304         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3305         /* 0x40000000 = D3DSI_COISSUE */
3306         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3307         0x0000ffff                                                              /* end                      */
3308     };
3309     DWORD shader_code_12_coissue[] =  {
3310         0xffff0102,                                                             /* ps_1_2                   */
3311         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3312         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3313         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3314         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3315         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3316         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3317         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3318         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3319         /* 0x40000000 = D3DSI_COISSUE */
3320         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3321         0x0000ffff                                                              /* end                      */
3322     };
3323     DWORD shader_code_13_coissue[] =  {
3324         0xffff0103,                                                             /* ps_1_3                   */
3325         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3326         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3327         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3328         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3329         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3330         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3331         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3332         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3333         /* 0x40000000 = D3DSI_COISSUE */
3334         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3335         0x0000ffff                                                              /* end                      */
3336     };
3337     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
3338      * compare against 0.5
3339      */
3340     DWORD shader_code_14_coissue[] =  {
3341         0xffff0104,                                                             /* ps_1_4                   */
3342         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
3343         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
3344         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
3345         /* 0x40000000 = D3DSI_COISSUE */
3346         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
3347         0x0000ffff                                                              /* end                      */
3348     };
3349     float quad1[] = {
3350         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
3351          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
3352         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
3353          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
3354     };
3355     float quad2[] = {
3356          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
3357          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
3358          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
3359          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
3360     };
3361     float quad3[] = {
3362          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
3363          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
3364          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
3365          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
3366     };
3367     float quad4[] = {
3368         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
3369          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
3370         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
3371          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
3372     };
3373     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
3374     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
3375     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
3376     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
3377
3378     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3379     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3380
3381     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3382     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3383     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3384     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3385     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
3386     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3387     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3389     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
3390     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3391     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
3392     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3393     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
3394     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3395     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
3396     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3397
3398     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3399     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3400     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3401     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3402     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3403     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3404
3405     hr = IDirect3DDevice9_BeginScene(device);
3406     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3407     if(SUCCEEDED(hr))
3408     {
3409         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3410         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3411         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3412         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3413
3414         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3415         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3416         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3417         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3418
3419         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
3420         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3421         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
3422         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3423
3424         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3425         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3426         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3427         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3428
3429         hr = IDirect3DDevice9_EndScene(device);
3430         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3431     }
3432     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3433     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3434
3435     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3436     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3437
3438     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
3439     color = getPixelColor(device, 158, 118);
3440     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
3441     color = getPixelColor(device, 162, 118);
3442     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
3443     color = getPixelColor(device, 158, 122);
3444     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
3445     color = getPixelColor(device, 162, 122);
3446     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
3447
3448     /* 1.1 shader. All 3 components get set, based on the .w comparison */
3449     color = getPixelColor(device, 158, 358);
3450     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
3451     color = getPixelColor(device, 162, 358);
3452     ok(color == 0x00000000, "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
3453     color = getPixelColor(device, 158, 362);
3454     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
3455     color = getPixelColor(device, 162, 362);
3456     ok(color == 0x00000000, "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
3457
3458     /* 1.2 shader */
3459     color = getPixelColor(device, 478, 358);
3460     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
3461     color = getPixelColor(device, 482, 358);
3462     ok(color == 0x00000000, "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
3463     color = getPixelColor(device, 478, 362);
3464     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
3465     color = getPixelColor(device, 482, 362);
3466     ok(color == 0x00000000, "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
3467
3468     /* 1.3 shader */
3469     color = getPixelColor(device, 478, 118);
3470     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
3471     color = getPixelColor(device, 482, 118);
3472     ok(color == 0x00000000, "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
3473     color = getPixelColor(device, 478, 122);
3474     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
3475     color = getPixelColor(device, 482, 122);
3476     ok(color == 0x00000000, "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
3477
3478     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3479     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3480     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
3481     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3482     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
3483     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3484
3485     hr = IDirect3DDevice9_BeginScene(device);
3486     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3487     if(SUCCEEDED(hr))
3488     {
3489         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
3490         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3491         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3492         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3493
3494         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
3495         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3496         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3497         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3498
3499         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
3500         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3501         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
3502         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3503
3504         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
3505         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3507         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3508
3509         hr = IDirect3DDevice9_EndScene(device);
3510         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3511     }
3512     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3513     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3514
3515     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
3516      * that we swapped the values in c1 and c2 to make the other tests return some color
3517      */
3518     color = getPixelColor(device, 158, 118);
3519     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
3520     color = getPixelColor(device, 162, 118);
3521     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
3522     color = getPixelColor(device, 158, 122);
3523     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
3524     color = getPixelColor(device, 162, 122);
3525     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
3526
3527     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
3528     color = getPixelColor(device, 158, 358);
3529     ok(color == 0x0000ff00, "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
3530     color = getPixelColor(device, 162, 358);
3531     ok(color == 0x0000ff00, "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
3532     color = getPixelColor(device, 158, 362);
3533     ok(color == 0x0000ff00, "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
3534     color = getPixelColor(device, 162, 362);
3535     ok(color == 0x0000ff00, "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
3536
3537     /* 1.2 shader */
3538     color = getPixelColor(device, 478, 358);
3539     ok(color == 0x0000ff00, "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
3540     color = getPixelColor(device, 482, 358);
3541     ok(color == 0x0000ff00, "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
3542     color = getPixelColor(device, 478, 362);
3543     ok(color == 0x0000ff00, "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
3544     color = getPixelColor(device, 482, 362);
3545     ok(color == 0x0000ff00, "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
3546
3547     /* 1.3 shader */
3548     color = getPixelColor(device, 478, 118);
3549     ok(color == 0x0000ff00, "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
3550     color = getPixelColor(device, 482, 118);
3551     ok(color == 0x0000ff00, "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
3552     color = getPixelColor(device, 478, 122);
3553     ok(color == 0x0000ff00, "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
3554     color = getPixelColor(device, 482, 122);
3555     ok(color == 0x0000ff00, "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
3556
3557     IDirect3DPixelShader9_Release(shader_14_coissue);
3558     IDirect3DPixelShader9_Release(shader_13_coissue);
3559     IDirect3DPixelShader9_Release(shader_12_coissue);
3560     IDirect3DPixelShader9_Release(shader_11_coissue);
3561     IDirect3DPixelShader9_Release(shader_14);
3562     IDirect3DPixelShader9_Release(shader_13);
3563     IDirect3DPixelShader9_Release(shader_12);
3564     IDirect3DPixelShader9_Release(shader_11);
3565 }
3566
3567 START_TEST(visual)
3568 {
3569     IDirect3DDevice9 *device_ptr;
3570     D3DCAPS9 caps;
3571     HRESULT hr;
3572     DWORD color;
3573
3574     d3d9_handle = LoadLibraryA("d3d9.dll");
3575     if (!d3d9_handle)
3576     {
3577         skip("Could not load d3d9.dll\n");
3578         return;
3579     }
3580
3581     device_ptr = init_d3d9();
3582     if (!device_ptr)
3583     {
3584         skip("Creating the device failed\n");
3585         return;
3586     }
3587
3588     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
3589
3590     /* Check for the reliability of the returned data */
3591     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3592     if(FAILED(hr))
3593     {
3594         trace("Clear failed, can't assure correctness of the test results, skipping\n");
3595         goto cleanup;
3596     }
3597     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
3598
3599     color = getPixelColor(device_ptr, 1, 1);
3600     if(color !=0x00ff0000)
3601     {
3602         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3603         goto cleanup;
3604     }
3605
3606     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3607     if(FAILED(hr))
3608     {
3609         trace("Clear failed, can't assure correctness of the test results, skipping\n");
3610         goto cleanup;
3611     }
3612     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
3613
3614     color = getPixelColor(device_ptr, 639, 479);
3615     if(color != 0x0000ddee)
3616     {
3617         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3618         goto cleanup;
3619     }
3620
3621     /* Now execute the real tests */
3622     lighting_test(device_ptr);
3623     clear_test(device_ptr);
3624     fog_test(device_ptr);
3625     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
3626     {
3627         test_cube_wrap(device_ptr);
3628     } else {
3629         skip("No cube texture support\n");
3630     }
3631     z_range_test(device_ptr);
3632     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
3633     {
3634         maxmip_test(device_ptr);
3635     }
3636     else
3637     {
3638         skip("No mipmap support\n");
3639     }
3640     offscreen_test(device_ptr);
3641     release_buffer_test(device_ptr);
3642     float_texture_test(device_ptr);
3643     texture_transform_flags_test(device_ptr);
3644     autogen_mipmap_test(device_ptr);
3645
3646
3647     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3648     {
3649         test_constant_clamp_vs(device_ptr);
3650     }
3651     else skip("No vs_1_1 support\n");
3652
3653     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
3654     {
3655         test_mova(device_ptr);
3656     }
3657     else skip("No vs_2_0 support\n");
3658
3659     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
3660     {
3661         fog_with_shader_test(device_ptr);
3662     }
3663     else skip("No vs_1_1 and ps_1_1 support\n");
3664
3665     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
3666     {
3667         texbem_test(device_ptr);
3668         texdepth_test(device_ptr);
3669         texkill_test(device_ptr);
3670         x8l8v8u8_test(device_ptr);
3671         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
3672             constant_clamp_ps_test(device_ptr);
3673             cnd_test(device_ptr);
3674         }
3675     }
3676     else skip("No ps_1_1 support\n");
3677
3678 cleanup:
3679     if(device_ptr) IDirect3DDevice9_Release(device_ptr);
3680 }