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