advapi32: Create MachineGuid value if it doesn't exist.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007 Henri Verbeet
3  * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include <dxerr9.h>
34 #include "wine/test.h"
35
36 static HMODULE d3d9_handle = 0;
37
38 static HWND create_window(void)
39 {
40     WNDCLASS wc = {0};
41     HWND ret;
42     wc.lpfnWndProc = &DefWindowProc;
43     wc.lpszClassName = "d3d9_test_wc";
44     RegisterClass(&wc);
45
46     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
47                         WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
48     return ret;
49 }
50
51 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
52 {
53     DWORD ret;
54     IDirect3DSurface9 *surf;
55     HRESULT hr;
56     D3DLOCKED_RECT lockedRect;
57     RECT rectToLock = {x, y, x+1, y+1};
58
59     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
60     if(FAILED(hr) || !surf )  /* This is not a test */
61     {
62         trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
63         return 0xdeadbeef;
64     }
65
66     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
67     if(FAILED(hr))
68     {
69         trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
70         ret = 0xdeadbeed;
71         goto out;
72     }
73
74     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
75     if(FAILED(hr))
76     {
77         trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
78         ret = 0xdeadbeec;
79         goto out;
80     }
81
82     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
83      * really important for these tests
84      */
85     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
86     hr = IDirect3DSurface9_UnlockRect(surf);
87     if(FAILED(hr))
88     {
89         trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
90     }
91
92 out:
93     if(surf) IDirect3DSurface9_Release(surf);
94     return ret;
95 }
96
97 static IDirect3DDevice9 *init_d3d9(void)
98 {
99     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
100     IDirect3D9 *d3d9_ptr = 0;
101     IDirect3DDevice9 *device_ptr = 0;
102     D3DPRESENT_PARAMETERS present_parameters;
103     HRESULT hr;
104
105     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
106     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
107     if (!d3d9_create) return NULL;
108
109     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
110     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
111     if (!d3d9_ptr) return NULL;
112
113     ZeroMemory(&present_parameters, sizeof(present_parameters));
114     present_parameters.Windowed = FALSE;
115     present_parameters.hDeviceWindow = create_window();
116     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
117     present_parameters.BackBufferWidth = 640;
118     present_parameters.BackBufferHeight = 480;
119     present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
120     present_parameters.EnableAutoDepthStencil = TRUE;
121     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
122
123     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
124     if(FAILED(hr)) {
125         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
126         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
127     }
128     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
129
130     return device_ptr;
131 }
132
133 struct vertex
134 {
135     float x, y, z;
136     DWORD diffuse;
137 };
138
139 struct tvertex
140 {
141     float x, y, z, rhw;
142     DWORD diffuse;
143 };
144
145 struct nvertex
146 {
147     float x, y, z;
148     float nx, ny, nz;
149     DWORD diffuse;
150 };
151
152 static void lighting_test(IDirect3DDevice9 *device)
153 {
154     HRESULT hr;
155     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
156     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
157     DWORD color;
158
159     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
160                       0.0f, 1.0f, 0.0f, 0.0f,
161                       0.0f, 0.0f, 1.0f, 0.0f,
162                       0.0f, 0.0f, 0.0f, 1.0f };
163
164     struct vertex unlitquad[] =
165     {
166         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
167         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
168         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
169         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
170     };
171     struct vertex litquad[] =
172     {
173         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
174         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
175         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
176         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
177     };
178     struct nvertex unlitnquad[] =
179     {
180         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
181         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
182         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
183         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
184     };
185     struct nvertex litnquad[] =
186     {
187         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
188         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
189         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
190         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
191     };
192     WORD Indices[] = {0, 1, 2, 2, 3, 0};
193
194     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
195     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
196
197     /* Setup some states that may cause issues */
198     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
199     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
200     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
201     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
202     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
203     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
204     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
205     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
206     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
207     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
208     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
209     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
210     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
211     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
212     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
213     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
214     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
215     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
216     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
217     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
218     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
219     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
220     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
221     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
222
223     hr = IDirect3DDevice9_SetFVF(device, fvf);
224     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
225
226     hr = IDirect3DDevice9_BeginScene(device);
227     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
228     if(hr == D3D_OK)
229     {
230         /* No lights are defined... That means, lit vertices should be entirely black */
231         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
232         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
233         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
234                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
235         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
236
237         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
238         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
239         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
240                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
241         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
242
243         hr = IDirect3DDevice9_SetFVF(device, nfvf);
244         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
245
246         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
247         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
248         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
249                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
250         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
251
252         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
253         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
254         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
255                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
256         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
257
258         IDirect3DDevice9_EndScene(device);
259         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
260     }
261
262     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
263
264     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
265     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
266     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
267     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
268     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
269     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
270     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
271     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
272
273     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
274     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
275 }
276
277 static void clear_test(IDirect3DDevice9 *device)
278 {
279     /* Tests the correctness of clearing parameters */
280     HRESULT hr;
281     D3DRECT rect[2];
282     D3DRECT rect_negneg;
283     DWORD color;
284     D3DVIEWPORT9 old_vp, vp;
285     RECT scissor;
286     DWORD oldColorWrite;
287     BOOL invalid_clear_failed = FALSE;
288
289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
290     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
291
292     /* Positive x, negative y */
293     rect[0].x1 = 0;
294     rect[0].y1 = 480;
295     rect[0].x2 = 320;
296     rect[0].y2 = 240;
297
298     /* Positive x, positive y */
299     rect[1].x1 = 0;
300     rect[1].y1 = 0;
301     rect[1].x2 = 320;
302     rect[1].y2 = 240;
303     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
304      * returns D3D_OK, but ignores the rectangle silently
305      */
306     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
307     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
308     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
309
310     /* negative x, negative y */
311     rect_negneg.x1 = 640;
312     rect_negneg.y1 = 240;
313     rect_negneg.x2 = 320;
314     rect_negneg.y2 = 0;
315     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
316     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
317     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
318
319     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
320
321     color = getPixelColor(device, 160, 360); /* lower left quad */
322     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
323     color = getPixelColor(device, 160, 120); /* upper left quad */
324     if(invalid_clear_failed) {
325         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
326         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
327     } else {
328         /* If the negative rectangle was dropped silently, the correct ones are cleared */
329         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
330     }
331     color = getPixelColor(device, 480, 360); /* lower right quad  */
332     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
333     color = getPixelColor(device, 480, 120); /* upper right quad */
334     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
335
336     /* Test how the viewport affects clears */
337     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
338     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
339     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
340     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
341
342     vp.X = 160;
343     vp.Y = 120;
344     vp.Width = 160;
345     vp.Height = 120;
346     vp.MinZ = 0.0;
347     vp.MaxZ = 1.0;
348     hr = IDirect3DDevice9_SetViewport(device, &vp);
349     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
350     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
351     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
352
353     vp.X = 320;
354     vp.Y = 240;
355     vp.Width = 320;
356     vp.Height = 240;
357     vp.MinZ = 0.0;
358     vp.MaxZ = 1.0;
359     hr = IDirect3DDevice9_SetViewport(device, &vp);
360     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
361     rect[0].x1 = 160;
362     rect[0].y1 = 120;
363     rect[0].x2 = 480;
364     rect[0].y2 = 360;
365     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
366     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
367
368     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
369     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
370
371     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
372     color = getPixelColor(device, 158, 118);
373     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
374     color = getPixelColor(device, 162, 118);
375     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
376     color = getPixelColor(device, 158, 122);
377     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
378     color = getPixelColor(device, 162, 122);
379     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
380
381     color = getPixelColor(device, 318, 238);
382     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
383     color = getPixelColor(device, 322, 238);
384     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
385     color = getPixelColor(device, 318, 242);
386     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
387     color = getPixelColor(device, 322, 242);
388     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
389
390     color = getPixelColor(device, 478, 358);
391     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
392     color = getPixelColor(device, 482, 358);
393     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
394     color = getPixelColor(device, 478, 362);
395     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
396     color = getPixelColor(device, 482, 362);
397     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
398
399     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
400     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
401
402     scissor.left = 160;
403     scissor.right = 480;
404     scissor.top = 120;
405     scissor.bottom = 360;
406     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
407     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
408     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
409     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
410
411     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
412     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
413     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
414     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
415
416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
417     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
418
419     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
420     color = getPixelColor(device, 158, 118);
421     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
422     color = getPixelColor(device, 162, 118);
423     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
424     color = getPixelColor(device, 158, 122);
425     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
426     color = getPixelColor(device, 162, 122);
427     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
428
429     color = getPixelColor(device, 158, 358);
430     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
431     color = getPixelColor(device, 162, 358);
432     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
433     color = getPixelColor(device, 158, 358);
434     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
435     color = getPixelColor(device, 162, 362);
436     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
437
438     color = getPixelColor(device, 478, 118);
439     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
440     color = getPixelColor(device, 478, 122);
441     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
442     color = getPixelColor(device, 482, 122);
443     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
444     color = getPixelColor(device, 482, 358);
445     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
446
447     color = getPixelColor(device, 478, 358);
448     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
449     color = getPixelColor(device, 478, 362);
450     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
451     color = getPixelColor(device, 482, 358);
452     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
453     color = getPixelColor(device, 482, 362);
454     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
455
456     color = getPixelColor(device, 318, 238);
457     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
458     color = getPixelColor(device, 318, 242);
459     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
460     color = getPixelColor(device, 322, 238);
461     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
462     color = getPixelColor(device, 322, 242);
463     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
464
465     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
466     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
467     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
468     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
469
470     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
471     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
472
473     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
474     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
475
476     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
477
478     /* Colorwriteenable does not affect the clear */
479     color = getPixelColor(device, 320, 240);
480     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
481 }
482
483 typedef struct {
484     float in[4];
485     DWORD out;
486 } test_data_t;
487
488 /*
489  *  c7      mova    ARGB            mov     ARGB
490  * -2.4     -2      0x00ffff00      -3      0x00ff0000
491  * -1.6     -2      0x00ffff00      -2      0x00ffff00
492  * -0.4      0      0x0000ffff      -1      0x0000ff00
493  *  0.4      0      0x0000ffff       0      0x0000ffff
494  *  1.6      2      0x00ff00ff       1      0x000000ff
495  *  2.4      2      0x00ff00ff       2      0x00ff00ff
496  */
497 static void test_mova(IDirect3DDevice9 *device)
498 {
499     static const DWORD mova_test[] = {
500         0xfffe0200,                                                             /* vs_2_0                       */
501         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
502         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
503         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
504         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
505         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
506         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
507         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
508         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
509         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
510         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
511         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
512         0x0000ffff                                                              /* END                          */
513     };
514     static const DWORD mov_test[] = {
515         0xfffe0101,                                                             /* vs_1_1                       */
516         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
517         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
518         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
519         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
520         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
521         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
522         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
523         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
524         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
525         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
526         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
527         0x0000ffff                                                              /* END                          */
528     };
529
530     static const test_data_t test_data[2][6] = {
531         {
532             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
533             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
534             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
535             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
536             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
537             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
538         },
539         {
540             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
541             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
542             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
543             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
544             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
545             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
546         }
547     };
548
549     static const float quad[][3] = {
550         {-1.0f, -1.0f, 0.0f},
551         {-1.0f,  1.0f, 0.0f},
552         { 1.0f, -1.0f, 0.0f},
553         { 1.0f,  1.0f, 0.0f},
554     };
555
556     static const D3DVERTEXELEMENT9 decl_elements[] = {
557         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
558         D3DDECL_END()
559     };
560
561     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
562     IDirect3DVertexShader9 *mova_shader = NULL;
563     IDirect3DVertexShader9 *mov_shader = NULL;
564     HRESULT hr;
565     UINT i, j;
566
567     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
568     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
569     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
570     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
571     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
572     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
573     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
574     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
575
576     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
577     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
578     for(j = 0; j < 2; ++j)
579     {
580         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
581         {
582             DWORD color;
583
584             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
585             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
586
587             hr = IDirect3DDevice9_BeginScene(device);
588             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
589
590             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
591             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
592
593             hr = IDirect3DDevice9_EndScene(device);
594             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
595
596             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
597             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
598
599             color = getPixelColor(device, 320, 240);
600             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
601                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
602
603             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
604             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
605         }
606         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
607         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
608     }
609
610     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
611     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
612
613     IDirect3DVertexDeclaration9_Release(vertex_declaration);
614     IDirect3DVertexShader9_Release(mova_shader);
615     IDirect3DVertexShader9_Release(mov_shader);
616 }
617
618 struct sVertex {
619     float x, y, z;
620     DWORD diffuse;
621     DWORD specular;
622 };
623
624 struct sVertexT {
625     float x, y, z, rhw;
626     DWORD diffuse;
627     DWORD specular;
628 };
629
630 static void fog_test(IDirect3DDevice9 *device)
631 {
632     HRESULT hr;
633     DWORD color;
634     BYTE r, g, b;
635     float start = 0.0f, end = 1.0f;
636     D3DCAPS9 caps;
637     int i;
638
639     /* Gets full z based fog with linear fog, no fog with specular color */
640     struct sVertex unstransformed_1[] = {
641         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
642         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
643         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
644         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
645     };
646     /* Ok, I am too lazy to deal with transform matrices */
647     struct sVertex unstransformed_2[] = {
648         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
649         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
650         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
651         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
652     };
653     /* Untransformed ones. Give them a different diffuse color to make the test look
654      * nicer. It also makes making sure that they are drawn correctly easier.
655      */
656     struct sVertexT transformed_1[] = {
657         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
658         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
659         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
660         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
661     };
662     struct sVertexT transformed_2[] = {
663         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
664         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
665         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
666         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
667     };
668     struct vertex rev_fog_quads[] = {
669        {-1.0,   -1.0,   0.1,    0x000000ff},
670        {-1.0,    0.0,   0.1,    0x000000ff},
671        { 0.0,    0.0,   0.1,    0x000000ff},
672        { 0.0,   -1.0,   0.1,    0x000000ff},
673
674        { 0.0,   -1.0,   0.9,    0x000000ff},
675        { 0.0,    0.0,   0.9,    0x000000ff},
676        { 1.0,    0.0,   0.9,    0x000000ff},
677        { 1.0,   -1.0,   0.9,    0x000000ff},
678
679        { 0.0,    0.0,   0.4,    0x000000ff},
680        { 0.0,    1.0,   0.4,    0x000000ff},
681        { 1.0,    1.0,   0.4,    0x000000ff},
682        { 1.0,    0.0,   0.4,    0x000000ff},
683
684        {-1.0,    0.0,   0.7,    0x000000ff},
685        {-1.0,    1.0,   0.7,    0x000000ff},
686        { 0.0,    1.0,   0.7,    0x000000ff},
687        { 0.0,    0.0,   0.7,    0x000000ff},
688     };
689     WORD Indices[] = {0, 1, 2, 2, 3, 0};
690
691     memset(&caps, 0, sizeof(caps));
692     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
693     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
694     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
695     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
696
697     /* Setup initial states: No lighting, fog on, fog color */
698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
699     ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
701     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
702     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
703     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
704
705     /* First test: Both table fog and vertex fog off */
706     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
707     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
708     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
709     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
710
711     /* Start = 0, end = 1. Should be default, but set them */
712     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
713     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
714     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
715     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
716
717     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
718     {
719         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
720         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
721         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
722         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
723                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
724                                                      sizeof(unstransformed_1[0]));
725         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
726
727         /* That makes it use the Z value */
728         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
729         ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
730         /* Untransformed, vertex fog != none (or table fog != none):
731          * Use the Z value as input into the equation
732          */
733         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
734                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
735                                                      sizeof(unstransformed_1[0]));
736         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
737
738         /* transformed verts */
739         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
740         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
741         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
742         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
743                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
744                                                      sizeof(transformed_1[0]));
745         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
746
747         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
748         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
749         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
750          * equation
751          */
752         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
753                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
754                                                      sizeof(transformed_2[0]));
755
756         hr = IDirect3DDevice9_EndScene(device);
757         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
758     }
759     else
760     {
761         ok(FALSE, "BeginScene failed\n");
762     }
763
764     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
765     color = getPixelColor(device, 160, 360);
766     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
767     color = getPixelColor(device, 160, 120);
768     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
769     color = getPixelColor(device, 480, 120);
770     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
771     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
772     {
773         color = getPixelColor(device, 480, 360);
774         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
775     }
776     else
777     {
778         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
779          * The settings above result in no fogging with vertex fog
780          */
781         color = getPixelColor(device, 480, 120);
782         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
783         trace("Info: Table fog not supported by this device\n");
784     }
785
786     /* Now test the special case fogstart == fogend */
787     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
788     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
789
790     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
791     {
792         start = 512;
793         end = 512;
794         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
795         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
796         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
797         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
798
799         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
800         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
801         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
802         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
803         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
804         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
805
806         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
807          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
808          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
809          * The third transformed quad remains unfogged because the fogcoords are read from the specular
810          * color and has fixed fogstart and fogend.
811          */
812         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
813                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
814                 sizeof(unstransformed_1[0]));
815         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
816         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
817                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
818                 sizeof(unstransformed_1[0]));
819         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
820
821         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
822         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
823         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
824         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
825                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
826                 sizeof(transformed_1[0]));
827         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
828
829         hr = IDirect3DDevice9_EndScene(device);
830         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
831     }
832     else
833     {
834         ok(FALSE, "BeginScene failed\n");
835     }
836     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
837     color = getPixelColor(device, 160, 360);
838     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
839     color = getPixelColor(device, 160, 120);
840     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
841     color = getPixelColor(device, 480, 120);
842     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
843
844     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
845      * but without shaders it seems to work everywhere
846      */
847     end = 0.2;
848     start = 0.8;
849     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
850     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
851     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
852     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
853     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
854     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
855
856     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
857      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
858      * so skip this for now
859      */
860     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
861         const char *mode = (i ? "table" : "vertex");
862         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
863         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
864         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
865         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
866         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
867         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
868         hr = IDirect3DDevice9_BeginScene(device);
869         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
870         if(SUCCEEDED(hr)) {
871             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
872                                 4,  5,  6,  6,  7, 4,
873                                 8,  9, 10, 10, 11, 8,
874                             12, 13, 14, 14, 15, 12};
875
876             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
877                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
878                     sizeof(rev_fog_quads[0]));
879
880             hr = IDirect3DDevice9_EndScene(device);
881             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
882         }
883         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
884         color = getPixelColor(device, 160, 360);
885         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
886
887         color = getPixelColor(device, 160, 120);
888         r = (color & 0x00ff0000) >> 16;
889         g = (color & 0x0000ff00) >>  8;
890         b = (color & 0x000000ff);
891         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
892            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
893
894         color = getPixelColor(device, 480, 120);
895         r = (color & 0x00ff0000) >> 16;
896         g = (color & 0x0000ff00) >>  8;
897         b = (color & 0x000000ff);
898         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
899            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
900
901         color = getPixelColor(device, 480, 360);
902         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
903
904         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
905             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
906             break;
907         }
908     }
909     /* Turn off the fog master switch to avoid confusing other tests */
910     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
911     ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
912     start = 0.0;
913     end = 1.0;
914     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
915     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
916     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
917     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
918     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
919     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
921     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
922 }
923
924 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
925  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
926  * regardless of the actual addressing mode set. */
927 static void test_cube_wrap(IDirect3DDevice9 *device)
928 {
929     static const float quad[][6] = {
930         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
931         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
932         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
933         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
934     };
935
936     static const D3DVERTEXELEMENT9 decl_elements[] = {
937         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
938         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
939         D3DDECL_END()
940     };
941
942     static const struct {
943         D3DTEXTUREADDRESS mode;
944         const char *name;
945     } address_modes[] = {
946         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
947         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
948         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
949         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
950         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
951     };
952
953     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
954     IDirect3DCubeTexture9 *texture = NULL;
955     IDirect3DSurface9 *surface = NULL;
956     D3DLOCKED_RECT locked_rect;
957     HRESULT hr;
958     UINT x;
959     INT y, face;
960
961     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
962     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
963     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
964     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
965
966     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
967             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
968     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
969
970     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
971     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
972
973     for (y = 0; y < 128; ++y)
974     {
975         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
976         for (x = 0; x < 64; ++x)
977         {
978             *ptr++ = 0xffff0000;
979         }
980         for (x = 64; x < 128; ++x)
981         {
982             *ptr++ = 0xff0000ff;
983         }
984     }
985
986     hr = IDirect3DSurface9_UnlockRect(surface);
987     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
988
989     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
990             D3DPOOL_DEFAULT, &texture, NULL);
991     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
992
993     /* Create cube faces */
994     for (face = 0; face < 6; ++face)
995     {
996         IDirect3DSurface9 *face_surface = NULL;
997
998         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
999         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1000
1001         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1002         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1003
1004         IDirect3DSurface9_Release(face_surface);
1005     }
1006
1007     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1008     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1009
1010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1011     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1012     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1013     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1014     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1015     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1016
1017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1018     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1019
1020     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1021     {
1022         DWORD color;
1023
1024         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1025         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1026         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1027         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1028
1029         hr = IDirect3DDevice9_BeginScene(device);
1030         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1031
1032         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1033         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1034
1035         hr = IDirect3DDevice9_EndScene(device);
1036         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1037
1038         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1039         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1040
1041         /* Due to the nature of this test, we sample essentially at the edge
1042          * between two faces. Because of this it's undefined from which face
1043          * the driver will sample. Furtunately that's not important for this
1044          * test, since all we care about is that it doesn't sample from the
1045          * other side of the surface or from the border. */
1046         color = getPixelColor(device, 320, 240);
1047         ok(color == 0x00ff0000 || color == 0x000000ff,
1048                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1049                 color, address_modes[x].name);
1050
1051         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1052         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1053     }
1054
1055     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1056     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1057
1058     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1059     IDirect3DCubeTexture9_Release(texture);
1060     IDirect3DSurface9_Release(surface);
1061 }
1062
1063 static void offscreen_test(IDirect3DDevice9 *device)
1064 {
1065     HRESULT hr;
1066     IDirect3DTexture9 *offscreenTexture = NULL;
1067     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1068     DWORD color;
1069
1070     static const float quad[][5] = {
1071         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1072         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1073         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1074         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1075     };
1076
1077     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1078     ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1079
1080     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1081     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1082     if(!offscreenTexture) {
1083         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1084         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1085         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1086         if(!offscreenTexture) {
1087             skip("Cannot create an offscreen render target\n");
1088             goto out;
1089         }
1090     }
1091
1092     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1093     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1094     if(!backbuffer) {
1095         goto out;
1096     }
1097
1098     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1099     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1100     if(!offscreen) {
1101         goto out;
1102     }
1103
1104     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1105     ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1106
1107     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1108     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1109     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1110     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1111     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1112     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1113     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1114     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1116     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1117
1118     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1119         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1120         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1121         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1122         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1123
1124         /* Draw without textures - Should resut in a white quad */
1125         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1126         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1127
1128         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1129         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1130         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1131         ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1132
1133         /* This time with the texture */
1134         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1135         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1136
1137         IDirect3DDevice9_EndScene(device);
1138     }
1139
1140     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1141
1142     /* Center quad - should be white */
1143     color = getPixelColor(device, 320, 240);
1144     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1145     /* Some quad in the cleared part of the texture */
1146     color = getPixelColor(device, 170, 240);
1147     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1148     /* Part of the originally cleared back buffer */
1149     color = getPixelColor(device, 10, 10);
1150     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1151     if(0) {
1152         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1153          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1154          * the offscreen rendering mode this test would succeed or fail
1155          */
1156         color = getPixelColor(device, 10, 470);
1157         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1158     }
1159
1160 out:
1161     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1162
1163     /* restore things */
1164     if(backbuffer) {
1165         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1166         IDirect3DSurface9_Release(backbuffer);
1167     }
1168     if(offscreenTexture) {
1169         IDirect3DTexture9_Release(offscreenTexture);
1170     }
1171     if(offscreen) {
1172         IDirect3DSurface9_Release(offscreen);
1173     }
1174 }
1175
1176 /* This test tests fog in combination with shaders.
1177  * What's tested: linear fog (vertex and table) with pixel shader
1178  *                linear table fog with non foggy vertex shader
1179  *                vertex fog with foggy vertex shader
1180  * What's not tested: non linear fog with shader
1181  *                    table fog with foggy vertex shader
1182  */
1183 static void fog_with_shader_test(IDirect3DDevice9 *device)
1184 {
1185     HRESULT hr;
1186     DWORD color;
1187     union {
1188         float f;
1189         DWORD i;
1190     } start, end;
1191     unsigned int i, j;
1192
1193     /* basic vertex shader without fog computation ("non foggy") */
1194     static const DWORD vertex_shader_code1[] = {
1195         0xfffe0101,                                                             /* vs_1_1                       */
1196         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1197         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1198         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1199         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1200         0x0000ffff
1201     };
1202     /* basic vertex shader with reversed fog computation ("foggy") */
1203     static const DWORD vertex_shader_code2[] = {
1204         0xfffe0101,                                                             /* vs_1_1                        */
1205         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1206         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1207         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1208         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1209         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1210         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1211         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1212         0x0000ffff
1213     };
1214     /* basic pixel shader */
1215     static const DWORD pixel_shader_code[] = {
1216         0xffff0101,                                                             /* ps_1_1     */
1217         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1218         0x0000ffff
1219     };
1220
1221     static struct vertex quad[] = {
1222         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1223         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1224         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1225         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1226     };
1227
1228     static const D3DVERTEXELEMENT9 decl_elements[] = {
1229         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1230         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1231         D3DDECL_END()
1232     };
1233
1234     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1235     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1236     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1237
1238     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1239     static const struct test_data_t {
1240         int vshader;
1241         int pshader;
1242         D3DFOGMODE vfog;
1243         D3DFOGMODE tfog;
1244         unsigned int color[11];
1245     } test_data[] = {
1246         /* only pixel shader: */
1247         {0, 1, 0, 3,
1248         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1249         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1250         {0, 1, 1, 3,
1251         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1252         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1253         {0, 1, 2, 3,
1254         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1255         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1256         {0, 1, 3, 0,
1257         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1258         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1259         {0, 1, 3, 3,
1260         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1261         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1262
1263         /* vertex shader */
1264         {1, 0, 0, 0,
1265         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1266          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1267         {1, 0, 0, 3,
1268         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1269         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1270         {1, 0, 1, 3,
1271         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1272         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1273
1274         {1, 0, 2, 3,
1275         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1276         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1277         {1, 0, 3, 3,
1278         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1279         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1280
1281         /* vertex shader and pixel shader */
1282         {1, 1, 0, 3,
1283         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1284         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1285         {1, 1, 1, 3,
1286         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1287         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1288         {1, 1, 2, 3,
1289         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1290         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1291
1292         {1, 1, 3, 3,
1293         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1294         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1295
1296
1297 #if 0  /* FIXME: these fail on GeForce 8500 */
1298         /* foggy vertex shader */
1299         {2, 0, 0, 0,
1300         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1301          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1302         {2, 0, 1, 0,
1303         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1304          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1305         {2, 0, 2, 0,
1306         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1307          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1308         {2, 0, 3, 0,
1309         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1310          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1311 #endif
1312
1313         /* foggy vertex shader and pixel shader */
1314         {2, 1, 0, 0,
1315         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1316          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1317         {2, 1, 1, 0,
1318         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1319          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1320         {2, 1, 2, 0,
1321         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1322          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1323         {2, 1, 3, 0,
1324         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1325          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1326
1327     };
1328
1329     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1330     start.f=0.1f;
1331     end.f=0.9f;
1332
1333     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1334     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1335     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1336     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1337     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1338     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1339     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1340     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1341
1342     /* Setup initial states: No lighting, fog on, fog color */
1343     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1344     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1345     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1346     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1347     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1348     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1349     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1350     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1351
1352     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1353     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1354     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1355     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1356
1357     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1358     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1359     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1360     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1361     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1362
1363     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1364     {
1365         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1366         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1367         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1368         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1369         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1370         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1371         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1372         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1373
1374         for(j=0; j < 11; j++)
1375         {
1376             /* Don't use the whole zrange to prevent rounding errors */
1377             quad[0].z = 0.001f + (float)j / 10.02f;
1378             quad[1].z = 0.001f + (float)j / 10.02f;
1379             quad[2].z = 0.001f + (float)j / 10.02f;
1380             quad[3].z = 0.001f + (float)j / 10.02f;
1381
1382             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1383             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1384
1385             hr = IDirect3DDevice9_BeginScene(device);
1386             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1387
1388             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1389             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1390
1391             hr = IDirect3DDevice9_EndScene(device);
1392             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1393
1394             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1395
1396             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1397             color = getPixelColor(device, 128, 240);
1398             ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1399                     && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1400                     && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1401                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1402                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1403         }
1404     }
1405
1406     /* reset states */
1407     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1408     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1409     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1410     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1411     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1412     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1413     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1414     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1415
1416     IDirect3DVertexShader9_Release(vertex_shader[1]);
1417     IDirect3DVertexShader9_Release(vertex_shader[2]);
1418     IDirect3DPixelShader9_Release(pixel_shader[1]);
1419     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1420 }
1421
1422 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1423     unsigned int i, x, y;
1424     HRESULT hr;
1425     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1426     D3DLOCKED_RECT locked_rect;
1427
1428     /* Generate the textures */
1429     for(i=0; i<2; i++)
1430     {
1431         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1432                                             D3DPOOL_MANAGED, &texture[i], NULL);
1433         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1434
1435         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1436         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1437         for (y = 0; y < 128; ++y)
1438         {
1439             if(i)
1440             { /* Set up black texture with 2x2 texel white spot in the middle */
1441                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1442                 for (x = 0; x < 128; ++x)
1443                 {
1444                     if(y>62 && y<66 && x>62 && x<66)
1445                         *ptr++ = 0xffffffff;
1446                     else
1447                         *ptr++ = 0xff000000;
1448                 }
1449             }
1450             else
1451             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1452                * (if multiplied with bumpenvmat)
1453               */
1454                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1455                 for (x = 0; x < 128; ++x)
1456                 {
1457                     if(abs(x-64)>abs(y-64))
1458                     {
1459                         if(x < 64)
1460                             *ptr++ = 0xc000;
1461                         else
1462                             *ptr++ = 0x4000;
1463                     }
1464                     else
1465                     {
1466                         if(y < 64)
1467                             *ptr++ = 0x0040;
1468                         else
1469                             *ptr++ = 0x00c0;
1470                     }
1471                 }
1472             }
1473         }
1474         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1475         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1476
1477         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1478         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1479
1480         /* Disable texture filtering */
1481         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1482         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1483         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1484         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1485
1486         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1487         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1488         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1489         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1490     }
1491 }
1492
1493 /* test the behavior of the texbem instruction
1494  * with normal 2D and projective 2D textures
1495  */
1496 static void texbem_test(IDirect3DDevice9 *device)
1497 {
1498     HRESULT hr;
1499     DWORD color;
1500     int i;
1501
1502     static const DWORD pixel_shader_code[] = {
1503         0xffff0101,                         /* ps_1_1*/
1504         0x00000042, 0xb00f0000,             /* tex t0*/
1505         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1506         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1507         0x0000ffff
1508     };
1509     static const DWORD double_texbem_code[] =  {
1510         0xffff0103,                                         /* ps_1_3           */
1511         0x00000042, 0xb00f0000,                             /* tex t0           */
1512         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1513         0x00000042, 0xb00f0002,                             /* tex t2           */
1514         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1515         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1516         0x0000ffff                                          /* end              */
1517     };
1518
1519
1520     static const float quad[][7] = {
1521         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1522         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1523         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1524         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1525     };
1526     static const float quad_proj[][9] = {
1527         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1528         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1529         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1530         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1531     };
1532
1533     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1534         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1535         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1536         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1537         D3DDECL_END()
1538     },{
1539         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1540         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1541         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1542         D3DDECL_END()
1543     } };
1544
1545     /* use assymetric matrix to test loading */
1546     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1547
1548     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1549     IDirect3DPixelShader9       *pixel_shader       = NULL;
1550     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1551     D3DLOCKED_RECT locked_rect;
1552
1553     generate_bumpmap_textures(device);
1554
1555     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1556     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1557     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1558     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1559     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1560
1561     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1562     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1563
1564     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1565     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1566
1567     for(i=0; i<2; i++)
1568     {
1569         if(i)
1570         {
1571             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1572             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1573         }
1574
1575         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1576         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1577         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1578         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1579
1580         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1581         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1582         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1583         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1584
1585         hr = IDirect3DDevice9_BeginScene(device);
1586         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1587
1588         if(!i)
1589             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1590         else
1591             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1592         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1593
1594         hr = IDirect3DDevice9_EndScene(device);
1595         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1596
1597         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1598         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1599
1600         color = getPixelColor(device, 320-32, 240);
1601         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1602         color = getPixelColor(device, 320+32, 240);
1603         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1604         color = getPixelColor(device, 320, 240-32);
1605         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1606         color = getPixelColor(device, 320, 240+32);
1607         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1608
1609         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1610         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1611         IDirect3DPixelShader9_Release(pixel_shader);
1612
1613         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1614         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1615         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1616     }
1617
1618     /* clean up */
1619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1620     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1621
1622     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1623     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1624
1625     for(i=0; i<2; i++)
1626     {
1627         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1628         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1629         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1630         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1631         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1632         IDirect3DTexture9_Release(texture);
1633     }
1634
1635     /* Test double texbem */
1636     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1637     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1638     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1639     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1640     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1641     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1642     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1643     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1644
1645     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1646     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1647     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1648     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1649
1650     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1651     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1652
1653     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1654     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1655     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1656     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1657     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1658     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1659
1660     {
1661         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1662 #define tex  0x00ff0000
1663 #define tex1 0x0000ff00
1664 #define origin 0x000000ff
1665         static const DWORD pixel_data[] = {
1666             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1667             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1668             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1669             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1670             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1671             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1672             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1673             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1674         };
1675 #undef tex1
1676 #undef tex2
1677 #undef origin
1678
1679         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1680         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1681         for(i = 0; i < 8; i++) {
1682             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1683         }
1684         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1685         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1686     }
1687
1688     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1689     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1690     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1691     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1692     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1693     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1694     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1695     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1696     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1697     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1698     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1699     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1700
1701     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1702     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1703     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1704     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1705     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1706     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1707
1708     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1709     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1710     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1711     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1712     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1713     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1714
1715     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1716     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1717     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1718     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1719     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1720     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1721     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1722     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1723
1724     hr = IDirect3DDevice9_BeginScene(device);
1725     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1726     if(SUCCEEDED(hr)) {
1727         static const float double_quad[] = {
1728             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1729              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1730             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1731              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1732         };
1733
1734         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1735         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1736         hr = IDirect3DDevice9_EndScene(device);
1737         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1738     }
1739     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1740     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1741     color = getPixelColor(device, 320, 240);
1742     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1743
1744     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1745     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1746     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1747     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1748     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1749     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1750     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1751     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1752     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1753     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1754
1755     IDirect3DPixelShader9_Release(pixel_shader);
1756     IDirect3DTexture9_Release(texture);
1757     IDirect3DTexture9_Release(texture1);
1758     IDirect3DTexture9_Release(texture2);
1759 }
1760
1761 static void z_range_test(IDirect3DDevice9 *device)
1762 {
1763     const struct vertex quad[] =
1764     {
1765         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1766         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1767         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1768         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1769     };
1770     const struct vertex quad2[] =
1771     {
1772         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1773         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1774         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1775         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1776     };
1777
1778     const struct tvertex quad3[] =
1779     {
1780         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1781         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1782         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1783         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1784     };
1785     const struct tvertex quad4[] =
1786     {
1787         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1788         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1789         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1790         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1791     };
1792     HRESULT hr;
1793     DWORD color;
1794     IDirect3DVertexShader9 *shader;
1795     IDirect3DVertexDeclaration9 *decl;
1796     D3DCAPS9 caps;
1797     const DWORD shader_code[] = {
1798         0xfffe0101,                                     /* vs_1_1           */
1799         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1800         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1801         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1802         0x0000ffff                                      /* end              */
1803     };
1804     static const D3DVERTEXELEMENT9 decl_elements[] = {
1805         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1806         D3DDECL_END()
1807     };
1808     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1809      * then call Present. Then clear the color buffer to make sure it has some defined content
1810      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1811      * by the depth value.
1812      */
1813     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1814     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1815     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1816     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1817
1818     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1819     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1820     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1821     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1822     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1823     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1824     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1825     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1826     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1827     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1828
1829     hr = IDirect3DDevice9_BeginScene(device);
1830     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1831     if(hr == D3D_OK)
1832     {
1833         /* Test the untransformed vertex path */
1834         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1835         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1836         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1837         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1838         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1839         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1840
1841         /* Test the transformed vertex path */
1842         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1843         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1844
1845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1846         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1847         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1848         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1849         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1850         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1851
1852         hr = IDirect3DDevice9_EndScene(device);
1853         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1854     }
1855
1856     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1857     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1858
1859     /* Do not test the exact corner pixels, but go pretty close to them */
1860
1861     /* Clipped because z > 1.0 */
1862     color = getPixelColor(device, 28, 238);
1863     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1864     color = getPixelColor(device, 28, 241);
1865     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1866
1867     /* Not clipped, > z buffer clear value(0.75) */
1868     color = getPixelColor(device, 31, 238);
1869     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1870     color = getPixelColor(device, 31, 241);
1871     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1872     color = getPixelColor(device, 100, 238);
1873     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1874     color = getPixelColor(device, 100, 241);
1875     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1876
1877     /* Not clipped, < z buffer clear value */
1878     color = getPixelColor(device, 104, 238);
1879     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1880     color = getPixelColor(device, 104, 241);
1881     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1882     color = getPixelColor(device, 318, 238);
1883     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1884     color = getPixelColor(device, 318, 241);
1885     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1886
1887     /* Clipped because z < 0.0 */
1888     color = getPixelColor(device, 321, 238);
1889     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890     color = getPixelColor(device, 321, 241);
1891     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1892
1893     /* Test the shader path */
1894     IDirect3DDevice9_GetDeviceCaps(device, &caps);
1895     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1896         skip("Vertex shaders not supported\n");
1897         goto out;
1898     }
1899     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1901     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1903
1904     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1905
1906     IDirect3DDevice9_SetVertexDeclaration(device, decl);
1907     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1908     IDirect3DDevice9_SetVertexShader(device, shader);
1909     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1910
1911     hr = IDirect3DDevice9_BeginScene(device);
1912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1913     if(hr == D3D_OK)
1914     {
1915         float colorf[] = {1.0, 0.0, 0.0, 1.0};
1916         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1917         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1919         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1920         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1921         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1922         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1923         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1924         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1925
1926         hr = IDirect3DDevice9_EndScene(device);
1927         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1928     }
1929
1930     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1931     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1932     IDirect3DDevice9_SetVertexShader(device, NULL);
1933     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1934
1935     IDirect3DVertexDeclaration9_Release(decl);
1936     IDirect3DVertexShader9_Release(shader);
1937
1938     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1939     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1940     /* Z < 1.0 */
1941     color = getPixelColor(device, 28, 238);
1942     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1943
1944     /* 1.0 < z < 0.75 */
1945     color = getPixelColor(device, 31, 238);
1946     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1947     color = getPixelColor(device, 100, 238);
1948     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1949
1950     /* 0.75 < z < 0.0 */
1951     color = getPixelColor(device, 104, 238);
1952     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1953     color = getPixelColor(device, 318, 238);
1954     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1955
1956     /* 0.0 < z */
1957     color = getPixelColor(device, 321, 238);
1958     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1959
1960     out:
1961     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
1962     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1963     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1964     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1965     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1966     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1967 }
1968
1969 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
1970 {
1971     D3DSURFACE_DESC desc;
1972     D3DLOCKED_RECT l;
1973     HRESULT hr;
1974     unsigned int x, y;
1975     DWORD *mem;
1976
1977     memset(&desc, 0, sizeof(desc));
1978     memset(&l, 0, sizeof(l));
1979     hr = IDirect3DSurface9_GetDesc(surface, &desc);
1980     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
1981     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
1982     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
1983     if(FAILED(hr)) return;
1984
1985     for(y = 0; y < desc.Height; y++)
1986     {
1987         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
1988         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
1989         {
1990             mem[x] = color;
1991         }
1992     }
1993     hr = IDirect3DSurface9_UnlockRect(surface);
1994     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
1995 }
1996
1997 static void maxmip_test(IDirect3DDevice9 *device)
1998 {
1999     IDirect3DTexture9 *texture = NULL;
2000     IDirect3DSurface9 *surface = NULL;
2001     HRESULT hr;
2002     DWORD color;
2003     const float quads[] = {
2004         -1.0,   -1.0,   0.0,    0.0,    0.0,
2005         -1.0,    0.0,   0.0,    0.0,    1.0,
2006          0.0,   -1.0,   0.0,    1.0,    0.0,
2007          0.0,    0.0,   0.0,    1.0,    1.0,
2008
2009          0.0,   -1.0,   0.0,    0.0,    0.0,
2010          0.0,    0.0,   0.0,    0.0,    1.0,
2011          1.0,   -1.0,   0.0,    1.0,    0.0,
2012          1.0,    0.0,   0.0,    1.0,    1.0,
2013
2014          0.0,    0.0,   0.0,    0.0,    0.0,
2015          0.0,    1.0,   0.0,    0.0,    1.0,
2016          1.0,    0.0,   0.0,    1.0,    0.0,
2017          1.0,    1.0,   0.0,    1.0,    1.0,
2018
2019         -1.0,    0.0,   0.0,    0.0,    0.0,
2020         -1.0,    1.0,   0.0,    0.0,    1.0,
2021          0.0,    0.0,   0.0,    1.0,    0.0,
2022          0.0,    1.0,   0.0,    1.0,    1.0,
2023     };
2024
2025     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2026     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2027
2028     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2029                                         &texture, NULL);
2030     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2031     if(!texture)
2032     {
2033         skip("Failed to create test texture\n");
2034         return;
2035     }
2036
2037     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2038     fill_surface(surface, 0xffff0000);
2039     IDirect3DSurface9_Release(surface);
2040     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2041     fill_surface(surface, 0xff00ff00);
2042     IDirect3DSurface9_Release(surface);
2043     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2044     fill_surface(surface, 0xff0000ff);
2045     IDirect3DSurface9_Release(surface);
2046
2047     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2048     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2049     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2050     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2051
2052     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2053     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2054
2055     hr = IDirect3DDevice9_BeginScene(device);
2056     if(SUCCEEDED(hr))
2057     {
2058         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2059         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2060         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2061         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2062
2063         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2064         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2065         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2066         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2067
2068         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2069         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2070         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2071         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2072
2073         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2074         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2075         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2076         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2077         hr = IDirect3DDevice9_EndScene(device);
2078     }
2079
2080     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2081     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2082     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2083     color = getPixelColor(device, 160, 360);
2084     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2085     color = getPixelColor(device, 160, 120);
2086     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2087     color = getPixelColor(device, 480, 120);
2088     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2089     color = getPixelColor(device, 480, 360);
2090     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2091
2092     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2093     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2094
2095     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2096     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2097
2098     hr = IDirect3DDevice9_BeginScene(device);
2099     if(SUCCEEDED(hr))
2100     {
2101         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2102         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2103         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2104         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2105
2106         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2107         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2109         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2110
2111         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2112         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2113         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2114         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2115
2116         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2117         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2118         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2119         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2120         hr = IDirect3DDevice9_EndScene(device);
2121     }
2122
2123     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2124     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2125     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2126     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2127
2128     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2129     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2130     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2131      * samples from the highest level in the texture(level 2)
2132      */
2133     color = getPixelColor(device, 160, 360);
2134     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2135     color = getPixelColor(device, 160, 120);
2136     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2137     color = getPixelColor(device, 480, 120);
2138     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2139     color = getPixelColor(device, 480, 360);
2140     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2141
2142     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2143     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2144     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2145     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2146     IDirect3DTexture9_Release(texture);
2147 }
2148
2149 static void release_buffer_test(IDirect3DDevice9 *device)
2150 {
2151     IDirect3DVertexBuffer9 *vb = NULL;
2152     IDirect3DIndexBuffer9 *ib = NULL;
2153     HRESULT hr;
2154     BYTE *data;
2155     long ref;
2156
2157     static const struct vertex quad[] = {
2158         {-1.0,      -1.0,       0.1,        0xffff0000},
2159         {-1.0,       1.0,       0.1,        0xffff0000},
2160         { 1.0,       1.0,       0.1,        0xffff0000},
2161
2162         {-1.0,      -1.0,       0.1,        0xff00ff00},
2163         {-1.0,       1.0,       0.1,        0xff00ff00},
2164         { 1.0,       1.0,       0.1,        0xff00ff00}
2165     };
2166     short indices[] = {3, 4, 5};
2167
2168     /* Index and vertex buffers should always be creatable */
2169     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2170                                               D3DPOOL_MANAGED, &vb, NULL);
2171     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2172     if(!vb) {
2173         skip("Failed to create a vertex buffer\n");
2174         return;
2175     }
2176     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2177     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2178     if(!ib) {
2179         skip("Failed to create an index buffer\n");
2180         return;
2181     }
2182
2183     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2184     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2185     memcpy(data, quad, sizeof(quad));
2186     hr = IDirect3DVertexBuffer9_Unlock(vb);
2187     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2188
2189     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2190     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2191     memcpy(data, indices, sizeof(indices));
2192     hr = IDirect3DIndexBuffer9_Unlock(ib);
2193     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2194
2195     hr = IDirect3DDevice9_SetIndices(device, ib);
2196     ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2197     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2198     ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2199     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2200     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2201
2202     /* Now destroy the bound index buffer and draw again */
2203     ref = IDirect3DIndexBuffer9_Release(ib);
2204     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2205
2206     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2207     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2208
2209     hr = IDirect3DDevice9_BeginScene(device);
2210     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2211     if(SUCCEEDED(hr))
2212     {
2213         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2214          * making assumptions about the indices or vertices
2215          */
2216         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2217         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2218         hr = IDirect3DDevice9_EndScene(device);
2219         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2220     }
2221
2222     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2223     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2224
2225     hr = IDirect3DDevice9_SetIndices(device, NULL);
2226     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2227     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2228     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2229
2230     /* Index buffer was already destroyed as part of the test */
2231     IDirect3DVertexBuffer9_Release(vb);
2232 }
2233
2234 static void float_texture_test(IDirect3DDevice9 *device)
2235 {
2236     IDirect3D9 *d3d = NULL;
2237     HRESULT hr;
2238     IDirect3DTexture9 *texture = NULL;
2239     D3DLOCKED_RECT lr;
2240     float *data;
2241     DWORD color;
2242     float quad[] = {
2243         -1.0,      -1.0,       0.1,     0.0,    0.0,
2244         -1.0,       1.0,       0.1,     0.0,    1.0,
2245          1.0,      -1.0,       0.1,     1.0,    0.0,
2246          1.0,       1.0,       0.1,     1.0,    1.0,
2247     };
2248
2249     memset(&lr, 0, sizeof(lr));
2250     IDirect3DDevice9_GetDirect3D(device, &d3d);
2251     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2252                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2253         skip("D3DFMT_R32F textures not supported\n");
2254         goto out;
2255     }
2256
2257     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2258                                         D3DPOOL_MANAGED, &texture, NULL);
2259     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2260     if(!texture) {
2261         skip("Failed to create R32F texture\n");
2262         goto out;
2263     }
2264
2265     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2266     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2267     data = lr.pBits;
2268     *data = 0.0;
2269     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2270     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2271
2272     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2274
2275     hr = IDirect3DDevice9_BeginScene(device);
2276     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2277     if(SUCCEEDED(hr))
2278     {
2279         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2280         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2281
2282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2283         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2284
2285         hr = IDirect3DDevice9_EndScene(device);
2286         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2287     }
2288     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2289     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2290
2291     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2292     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2293
2294     color = getPixelColor(device, 240, 320);
2295     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2296
2297 out:
2298     if(texture) IDirect3DTexture9_Release(texture);
2299     IDirect3D9_Release(d3d);
2300 }
2301
2302 static void g16r16_texture_test(IDirect3DDevice9 *device)
2303 {
2304     IDirect3D9 *d3d = NULL;
2305     HRESULT hr;
2306     IDirect3DTexture9 *texture = NULL;
2307     D3DLOCKED_RECT lr;
2308     DWORD *data;
2309     DWORD color, red, green, blue;
2310     float quad[] = {
2311        -1.0,      -1.0,       0.1,     0.0,    0.0,
2312        -1.0,       1.0,       0.1,     0.0,    1.0,
2313         1.0,      -1.0,       0.1,     1.0,    0.0,
2314         1.0,       1.0,       0.1,     1.0,    1.0,
2315     };
2316
2317     memset(&lr, 0, sizeof(lr));
2318     IDirect3DDevice9_GetDirect3D(device, &d3d);
2319     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2320        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2321            skip("D3DFMT_G16R16 textures not supported\n");
2322            goto out;
2323     }
2324
2325     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2326                                         D3DPOOL_MANAGED, &texture, NULL);
2327     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2328     if(!texture) {
2329         skip("Failed to create D3DFMT_G16R16 texture\n");
2330         goto out;
2331     }
2332
2333     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2334     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2335     data = lr.pBits;
2336     *data = 0x0f00f000;
2337     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2338     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2339
2340     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2341     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2342
2343     hr = IDirect3DDevice9_BeginScene(device);
2344     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2345     if(SUCCEEDED(hr))
2346     {
2347         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2348         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2349
2350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2351         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2352
2353         hr = IDirect3DDevice9_EndScene(device);
2354         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2355     }
2356     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2357     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2358
2359     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2360     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2361
2362     color = getPixelColor(device, 240, 320);
2363     red   = (color & 0x00ff0000) >> 16;
2364     green = (color & 0x0000ff00) >>  8;
2365     blue  = (color & 0x000000ff) >>  0;
2366     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2367        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2368
2369 out:
2370     if(texture) IDirect3DTexture9_Release(texture);
2371     IDirect3D9_Release(d3d);
2372 }
2373
2374 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2375 {
2376     HRESULT hr;
2377     IDirect3D9 *d3d;
2378     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2379     D3DCAPS9 caps;
2380     IDirect3DTexture9 *texture = NULL;
2381     IDirect3DVolumeTexture9 *volume = NULL;
2382     unsigned int x, y, z;
2383     D3DLOCKED_RECT lr;
2384     D3DLOCKED_BOX lb;
2385     DWORD color;
2386     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2387     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2388                            0.0, 1.0, 0.0, 0.0,
2389                            0.0, 0.0, 1.0, 0.0,
2390                            0.0, 0.0, 0.0, 1.0};
2391     static const D3DVERTEXELEMENT9 decl_elements[] = {
2392         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2393         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2394         D3DDECL_END()
2395     };
2396     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2397         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2398         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2399         D3DDECL_END()
2400     };
2401     static const D3DVERTEXELEMENT9 decl_elements3[] = {
2402         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2403         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2404         D3DDECL_END()
2405     };
2406     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2407                                                  0x00, 0xff, 0x00, 0x00,
2408                                                  0x00, 0x00, 0x00, 0x00,
2409                                                  0x00, 0x00, 0x00, 0x00};
2410
2411     memset(&lr, 0, sizeof(lr));
2412     memset(&lb, 0, sizeof(lb));
2413     IDirect3DDevice9_GetDirect3D(device, &d3d);
2414     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2415                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2416         fmt = D3DFMT_A16B16G16R16;
2417     }
2418     IDirect3D9_Release(d3d);
2419
2420     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2421     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2422     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
2423     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2424     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
2425     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2426     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
2427     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
2428     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2429     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
2430     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2431     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
2432     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2433     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
2434     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2435     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
2436     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2437     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
2438     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
2439     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
2440     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2441     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
2442     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2443     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2444
2445     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2446     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
2447     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
2448                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
2449     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
2450     if(!texture) {
2451         skip("Failed to create the test texture\n");
2452         return;
2453     }
2454
2455     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
2456      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
2457      * 1.0 in red and green for the x and y coords
2458      */
2459     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2460     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
2461     for(y = 0; y < caps.MaxTextureHeight; y++) {
2462         for(x = 0; x < caps.MaxTextureWidth; x++) {
2463             double r_f = (double) y / (double) caps.MaxTextureHeight;
2464             double g_f = (double) x / (double) caps.MaxTextureWidth;
2465             if(fmt == D3DFMT_A16B16G16R16) {
2466                 unsigned short r, g;
2467                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
2468                 r = (unsigned short) (r_f * 65536.0);
2469                 g = (unsigned short) (g_f * 65536.0);
2470                 dst[0] = r;
2471                 dst[1] = g;
2472                 dst[2] = 0;
2473                 dst[3] = 65535;
2474             } else {
2475                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
2476                 unsigned char r = (unsigned char) (r_f * 255.0);
2477                 unsigned char g = (unsigned char) (g_f * 255.0);
2478                 dst[0] = 0;
2479                 dst[1] = g;
2480                 dst[2] = r;
2481                 dst[3] = 255;
2482             }
2483         }
2484     }
2485     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2486     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
2487     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2488     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2489
2490     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2491     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2492     hr = IDirect3DDevice9_BeginScene(device);
2493     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2494     if(SUCCEEDED(hr))
2495     {
2496         float quad1[] = {
2497             -1.0,      -1.0,       0.1,     1.0,    1.0,
2498             -1.0,       0.0,       0.1,     1.0,    1.0,
2499              0.0,      -1.0,       0.1,     1.0,    1.0,
2500              0.0,       0.0,       0.1,     1.0,    1.0,
2501         };
2502         float quad2[] = {
2503             -1.0,       0.0,       0.1,     1.0,    1.0,
2504             -1.0,       1.0,       0.1,     1.0,    1.0,
2505              0.0,       0.0,       0.1,     1.0,    1.0,
2506              0.0,       1.0,       0.1,     1.0,    1.0,
2507         };
2508         float quad3[] = {
2509              0.0,       0.0,       0.1,     0.5,    0.5,
2510              0.0,       1.0,       0.1,     0.5,    0.5,
2511              1.0,       0.0,       0.1,     0.5,    0.5,
2512              1.0,       1.0,       0.1,     0.5,    0.5,
2513         };
2514         float quad4[] = {
2515              320,       480,       0.1,     1.0,    0.0,    1.0,
2516              320,       240,       0.1,     1.0,    0.0,    1.0,
2517              640,       480,       0.1,     1.0,    0.0,    1.0,
2518              640,       240,       0.1,     1.0,    0.0,    1.0,
2519         };
2520         float mat[16] = {0.0, 0.0, 0.0, 0.0,
2521                           0.0, 0.0, 0.0, 0.0,
2522                           0.0, 0.0, 0.0, 0.0,
2523                           0.0, 0.0, 0.0, 0.0};
2524
2525         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
2526         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2527         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2528         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2529         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2530
2531         /* What happens with transforms enabled? */
2532         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2533         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2535         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2536
2537         /* What happens if 4 coords are used, but only 2 given ?*/
2538         mat[8] = 1.0;
2539         mat[13] = 1.0;
2540         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2541         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2542         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2543         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2545         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2546
2547         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
2548          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
2549          * due to the coords in the vertices. (turns out red, indeed)
2550          */
2551         memset(mat, 0, sizeof(mat));
2552         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2553         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2554         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
2555         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2556         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2557         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2558         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2559         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2560
2561         hr = IDirect3DDevice9_EndScene(device);
2562         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2563     }
2564     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2565     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2566     color = getPixelColor(device, 160, 360);
2567     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
2568     color = getPixelColor(device, 160, 120);
2569     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2570     color = getPixelColor(device, 480, 120);
2571     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
2572     color = getPixelColor(device, 480, 360);
2573     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
2574
2575     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2576     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2577
2578     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2579     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2580     hr = IDirect3DDevice9_BeginScene(device);
2581     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2582     if(SUCCEEDED(hr))
2583     {
2584         float quad1[] = {
2585             -1.0,      -1.0,       0.1,     0.8,    0.2,
2586             -1.0,       0.0,       0.1,     0.8,    0.2,
2587              0.0,      -1.0,       0.1,     0.8,    0.2,
2588              0.0,       0.0,       0.1,     0.8,    0.2,
2589         };
2590         float quad2[] = {
2591             -1.0,       0.0,       0.1,     0.5,    1.0,
2592             -1.0,       1.0,       0.1,     0.5,    1.0,
2593              0.0,       0.0,       0.1,     0.5,    1.0,
2594              0.0,       1.0,       0.1,     0.5,    1.0,
2595         };
2596         float quad3[] = {
2597              0.0,       0.0,       0.1,     0.5,    1.0,
2598              0.0,       1.0,       0.1,     0.5,    1.0,
2599              1.0,       0.0,       0.1,     0.5,    1.0,
2600              1.0,       1.0,       0.1,     0.5,    1.0,
2601         };
2602         float quad4[] = {
2603              0.0,      -1.0,       0.1,     0.8,    0.2,
2604              0.0,       0.0,       0.1,     0.8,    0.2,
2605              1.0,      -1.0,       0.1,     0.8,    0.2,
2606              1.0,       0.0,       0.1,     0.8,    0.2,
2607         };
2608         float mat[16] = {0.0, 0.0, 0.0, 0.0,
2609                           0.0, 0.0, 0.0, 0.0,
2610                           0.0, 1.0, 0.0, 0.0,
2611                           0.0, 0.0, 0.0, 0.0};
2612
2613         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
2614          */
2615         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2616         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2617         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2618         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2619
2620         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2621         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2622
2623         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
2624          * it behaves like COUNT2 because normal textures require 2 coords
2625          */
2626         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2627         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2628         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
2629         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2630
2631         /* Just to be sure, the same as quad2 above */
2632         memset(mat, 0, sizeof(mat));
2633         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2634         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2635         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2636         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2638         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2639
2640         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
2641          * used? And what happens to the first?
2642          */
2643         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2644         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2645         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2646         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2647
2648         hr = IDirect3DDevice9_EndScene(device);
2649         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2650     }
2651     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2652     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2653     color = getPixelColor(device, 160, 360);
2654     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
2655     color = getPixelColor(device, 160, 120);
2656     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2657     color = getPixelColor(device, 480, 120);
2658     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
2659        "quad 3 has color %08x, expected 0x00ff8000\n", color);
2660     color = getPixelColor(device, 480, 360);
2661     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
2662        "quad 4 has color %08x, expected 0x0033cc00\n", color);
2663
2664     IDirect3DTexture9_Release(texture);
2665
2666     /* Test projected textures, without any fancy matrices */
2667     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
2668     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2669     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
2670     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
2671     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
2672     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2673     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
2674     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2675
2676     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2677     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2678     for(x = 0; x < 4; x++) {
2679         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
2680     }
2681     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2682     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2683     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2684     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2685
2686     hr = IDirect3DDevice9_BeginScene(device);
2687     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2688     if(SUCCEEDED(hr))
2689     {
2690         const float proj_quads[] = {
2691            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
2692             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
2693            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
2694             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
2695            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
2696             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
2697            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
2698             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
2699         };
2700
2701         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2702         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2703         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
2704         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2705
2706         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
2707         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
2709         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2710
2711         hr = IDirect3DDevice9_EndScene(device);
2712         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2713     }
2714
2715     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2717     IDirect3DTexture9_Release(texture);
2718
2719     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2720     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2721     color = getPixelColor(device, 158, 118);
2722     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
2723     color = getPixelColor(device, 162, 118);
2724     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
2725     color = getPixelColor(device, 158, 122);
2726     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
2727     color = getPixelColor(device, 162, 122);
2728     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
2729
2730     color = getPixelColor(device, 158, 178);
2731     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
2732     color = getPixelColor(device, 162, 178);
2733     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
2734     color = getPixelColor(device, 158, 182);
2735     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
2736     color = getPixelColor(device, 162, 182);
2737     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
2738
2739     color = getPixelColor(device, 318, 118);
2740     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
2741     color = getPixelColor(device, 322, 118);
2742     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
2743     color = getPixelColor(device, 318, 122);
2744     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
2745     color = getPixelColor(device, 322, 122);
2746     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
2747
2748     color = getPixelColor(device, 318, 178);
2749     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
2750     color = getPixelColor(device, 322, 178);
2751     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
2752     color = getPixelColor(device, 318, 182);
2753     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
2754     color = getPixelColor(device, 322, 182);
2755     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
2756
2757     color = getPixelColor(device, 238, 298);
2758     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
2759     color = getPixelColor(device, 242, 298);
2760     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
2761     color = getPixelColor(device, 238, 302);
2762     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
2763     color = getPixelColor(device, 242, 302);
2764     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
2765
2766     color = getPixelColor(device, 238, 388);
2767     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
2768     color = getPixelColor(device, 242, 388);
2769     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
2770     color = getPixelColor(device, 238, 392);
2771     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
2772     color = getPixelColor(device, 242, 392);
2773     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
2774
2775     color = getPixelColor(device, 478, 298);
2776     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
2777     color = getPixelColor(device, 482, 298);
2778     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
2779     color = getPixelColor(device, 478, 302);
2780     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
2781     color = getPixelColor(device, 482, 302);
2782     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
2783
2784     color = getPixelColor(device, 478, 388);
2785     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
2786     color = getPixelColor(device, 482, 388);
2787     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
2788     color = getPixelColor(device, 478, 392);
2789     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
2790     color = getPixelColor(device, 482, 392);
2791     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
2792
2793     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
2794     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2795     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
2796      * Thus watch out if sampling from texels between 0 and 1.
2797      */
2798     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
2799     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
2800        "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
2801     if(!volume) {
2802         skip("Failed to create a volume texture\n");
2803         goto out;
2804     }
2805
2806     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
2807     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
2808     for(z = 0; z < 32; z++) {
2809         for(y = 0; y < 32; y++) {
2810             for(x = 0; x < 32; x++) {
2811                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
2812                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
2813                 float r_f = (float) x / 31.0;
2814                 float g_f = (float) y / 31.0;
2815                 float b_f = (float) z / 31.0;
2816
2817                 if(fmt == D3DFMT_A16B16G16R16) {
2818                     unsigned short *mem_s = mem;
2819                     mem_s[0]  = r_f * 65535.0;
2820                     mem_s[1]  = g_f * 65535.0;
2821                     mem_s[2]  = b_f * 65535.0;
2822                     mem_s[3]  = 65535;
2823                 } else {
2824                     unsigned char *mem_c = mem;
2825                     mem_c[0]  = b_f * 255.0;
2826                     mem_c[1]  = g_f * 255.0;
2827                     mem_c[2]  = r_f * 255.0;
2828                     mem_c[3]  = 255;
2829                 }
2830             }
2831         }
2832     }
2833     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
2834     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2835
2836     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
2837     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2838
2839     hr = IDirect3DDevice9_BeginScene(device);
2840     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2841     if(SUCCEEDED(hr))
2842     {
2843         float quad1[] = {
2844             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2845             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2846              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2847              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
2848         };
2849         float quad2[] = {
2850             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2851             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
2852              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2853              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
2854         };
2855         float quad3[] = {
2856              0.0,       0.0,       0.1,     0.0,    0.0,
2857              0.0,       1.0,       0.1,     0.0,    0.0,
2858              1.0,       0.0,       0.1,     0.0,    0.0,
2859              1.0,       1.0,       0.1,     0.0,    0.0
2860         };
2861         float quad4[] = {
2862              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2863              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2864              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2865              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
2866         };
2867         float mat[16] = {1.0, 0.0, 0.0, 0.0,
2868                          0.0, 0.0, 1.0, 0.0,
2869                          0.0, 1.0, 0.0, 0.0,
2870                          0.0, 0.0, 0.0, 1.0};
2871         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2872         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2873
2874         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
2875          * values
2876          */
2877         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2878         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2879         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2880         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2881         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2882         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2883
2884         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
2885          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
2886          * otherwise the w will be missing(blue).
2887          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
2888          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
2889          */
2890         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2891         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2892         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2893         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2894
2895         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
2896         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2897         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2898         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2899         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2900         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2901         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2902         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2903         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2904
2905         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
2906          * disable. ATI extends it up to the amount of values needed for the volume texture
2907          */
2908         memset(mat, 0, sizeof(mat));
2909         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2910         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2911         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2912         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2913         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2914         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2915         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2916         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2917
2918         hr = IDirect3DDevice9_EndScene(device);
2919         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2920     }
2921     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2922     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2923
2924     color = getPixelColor(device, 160, 360);
2925     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
2926     color = getPixelColor(device, 160, 120);
2927     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
2928        "quad 2 has color %08x, expected 0x00ffff00\n", color);
2929     color = getPixelColor(device, 480, 120);
2930     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
2931     color = getPixelColor(device, 480, 360);
2932     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
2933
2934     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
2935     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2936     hr = IDirect3DDevice9_BeginScene(device);
2937     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2938     if(SUCCEEDED(hr))
2939     {
2940         float quad1[] = {
2941             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2942             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2943              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2944              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
2945         };
2946         float quad2[] = {
2947             -1.0,       0.0,       0.1,
2948             -1.0,       1.0,       0.1,
2949              0.0,       0.0,       0.1,
2950              0.0,       1.0,       0.1,
2951         };
2952         float quad3[] = {
2953              0.0,       0.0,       0.1,     1.0,
2954              0.0,       1.0,       0.1,     1.0,
2955              1.0,       0.0,       0.1,     1.0,
2956              1.0,       1.0,       0.1,     1.0
2957         };
2958         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
2959                            0.0, 0.0, 0.0, 0.0,
2960                            0.0, 0.0, 0.0, 0.0,
2961                            0.0, 1.0, 0.0, 0.0};
2962         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
2963                            1.0, 0.0, 0.0, 0.0,
2964                            0.0, 1.0, 0.0, 0.0,
2965                            0.0, 0.0, 1.0, 0.0};
2966         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2967         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2968
2969         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
2970          */
2971         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2972         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2973         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2974         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2976         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2977
2978         /* None passed */
2979         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2980         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2981         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2982         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
2984         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2985
2986         /* 4 used, 1 passed */
2987         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
2988         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2989         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
2990         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2991         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
2992         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2993
2994         hr = IDirect3DDevice9_EndScene(device);
2995         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2996     }
2997     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2998     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2999     color = getPixelColor(device, 160, 360);
3000     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3001     color = getPixelColor(device, 160, 120);
3002     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3003     color = getPixelColor(device, 480, 120);
3004     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3005     /* Quad4: unused */
3006
3007     IDirect3DVolumeTexture9_Release(volume);
3008
3009     out:
3010     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3011     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3012     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3014     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3015     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3016     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3017     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3018     IDirect3DVertexDeclaration9_Release(decl);
3019     IDirect3DVertexDeclaration9_Release(decl2);
3020     IDirect3DVertexDeclaration9_Release(decl3);
3021 }
3022
3023 static void texdepth_test(IDirect3DDevice9 *device)
3024 {
3025     IDirect3DPixelShader9 *shader;
3026     HRESULT hr;
3027     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3028     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3029     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3030     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3031     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3032     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3033     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3034     DWORD shader_code[] = {
3035         0xffff0104,                                                                 /* ps_1_4               */
3036         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3037         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3038         0x0000fffd,                                                                 /* phase                */
3039         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3040         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3041         0x0000ffff                                                                  /* end                  */
3042     };
3043     DWORD color;
3044     float vertex[] = {
3045        -1.0,   -1.0,    0.0,
3046         1.0,   -1.0,    1.0,
3047        -1.0,    1.0,    0.0,
3048         1.0,    1.0,    1.0
3049     };
3050
3051     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3052     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3053
3054     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3055     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3059     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3061     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3062     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3063
3064     /* Fill the depth buffer with a gradient */
3065     hr = IDirect3DDevice9_BeginScene(device);
3066     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3067     if(SUCCEEDED(hr))
3068     {
3069         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3070         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3071         hr = IDirect3DDevice9_EndScene(device);
3072         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3073     }
3074
3075     /* Now perform the actual tests. Same geometry, but with the shader */
3076     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3077     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3078     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3079     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3080     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3081     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3082
3083     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3084     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3085     hr = IDirect3DDevice9_BeginScene(device);
3086     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3087     if(SUCCEEDED(hr))
3088     {
3089         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3090         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3091
3092         hr = IDirect3DDevice9_EndScene(device);
3093         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3094     }
3095
3096     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3097     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3098     color = getPixelColor(device, 158, 240);
3099     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3100     color = getPixelColor(device, 162, 240);
3101     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3102
3103     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3104
3105     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3106     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3107     hr = IDirect3DDevice9_BeginScene(device);
3108     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3109     if(SUCCEEDED(hr))
3110     {
3111         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3112         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3113
3114         hr = IDirect3DDevice9_EndScene(device);
3115         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3116     }
3117
3118     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3119     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3120     color = getPixelColor(device, 318, 240);
3121     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3122     color = getPixelColor(device, 322, 240);
3123     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3124
3125     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3126
3127     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3128     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3129     hr = IDirect3DDevice9_BeginScene(device);
3130     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3131     if(SUCCEEDED(hr))
3132     {
3133         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3134         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3135
3136         hr = IDirect3DDevice9_EndScene(device);
3137         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3138     }
3139     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3140     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3141
3142     color = getPixelColor(device, 1, 240);
3143     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3144
3145     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3146
3147     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3148     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3149     hr = IDirect3DDevice9_BeginScene(device);
3150     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3151     if(SUCCEEDED(hr))
3152     {
3153         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3154         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3155
3156         hr = IDirect3DDevice9_EndScene(device);
3157         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3158     }
3159     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3160     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3161     color = getPixelColor(device, 318, 240);
3162     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3163     color = getPixelColor(device, 322, 240);
3164     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3165
3166     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3167
3168     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3169     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3170     hr = IDirect3DDevice9_BeginScene(device);
3171     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3172     if(SUCCEEDED(hr))
3173     {
3174         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3175         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3176
3177         hr = IDirect3DDevice9_EndScene(device);
3178         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3179     }
3180     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3181     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3182
3183     color = getPixelColor(device, 1, 240);
3184     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3185
3186     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3187
3188     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3190     hr = IDirect3DDevice9_BeginScene(device);
3191     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3192     if(SUCCEEDED(hr))
3193     {
3194         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3195         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3196
3197         hr = IDirect3DDevice9_EndScene(device);
3198         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3199     }
3200     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3201     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3202
3203     color = getPixelColor(device, 638, 240);
3204     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3205
3206     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3207
3208     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3209     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3210     hr = IDirect3DDevice9_BeginScene(device);
3211     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3212     if(SUCCEEDED(hr))
3213     {
3214         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3215         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3216
3217         hr = IDirect3DDevice9_EndScene(device);
3218         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3219     }
3220     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3221     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3222
3223     color = getPixelColor(device, 638, 240);
3224     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3225
3226     /* Cleanup */
3227     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3228     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3229     IDirect3DPixelShader9_Release(shader);
3230
3231     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3232     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3233     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3234     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3235 }
3236
3237 static void texkill_test(IDirect3DDevice9 *device)
3238 {
3239     IDirect3DPixelShader9 *shader;
3240     HRESULT hr;
3241     DWORD color;
3242
3243     const float vertex[] = {
3244     /*                          bottom  top    right    left */
3245         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3246          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3247         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3248          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3249     };
3250
3251     DWORD shader_code_11[] = {
3252     0xffff0101,                                                             /* ps_1_1                     */
3253     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3254     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3255     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3256     0x0000ffff                                                              /* end                        */
3257     };
3258     DWORD shader_code_20[] = {
3259     0xffff0200,                                                             /* ps_2_0                     */
3260     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3261     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3262     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3263     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3264     0x0000ffff                                                              /* end                        */
3265     };
3266
3267     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3268     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3269     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3270     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3271
3272     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3273     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3274     hr = IDirect3DDevice9_BeginScene(device);
3275     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3276     if(SUCCEEDED(hr))
3277     {
3278         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3279         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3280         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3281         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3282         hr = IDirect3DDevice9_EndScene(device);
3283         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3284     }
3285     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3286     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3287     color = getPixelColor(device, 63, 46);
3288     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3289     color = getPixelColor(device, 66, 46);
3290     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3291     color = getPixelColor(device, 63, 49);
3292     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3293     color = getPixelColor(device, 66, 49);
3294     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3295
3296     color = getPixelColor(device, 578, 46);
3297     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3298     color = getPixelColor(device, 575, 46);
3299     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3300     color = getPixelColor(device, 578, 49);
3301     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3302     color = getPixelColor(device, 575, 49);
3303     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3304
3305     color = getPixelColor(device, 63, 430);
3306     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3307     color = getPixelColor(device, 63, 433);
3308     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3309     color = getPixelColor(device, 66, 433);
3310     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3311     color = getPixelColor(device, 66, 430);
3312     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3313
3314     color = getPixelColor(device, 578, 430);
3315     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3316     color = getPixelColor(device, 578, 433);
3317     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3318     color = getPixelColor(device, 575, 433);
3319     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3320     color = getPixelColor(device, 575, 430);
3321     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3322
3323     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3324     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3325     IDirect3DPixelShader9_Release(shader);
3326
3327     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3328     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3329     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3330     if(FAILED(hr)) {
3331         skip("Failed to create 2.0 test shader, most likely not supported\n");
3332         return;
3333     }
3334
3335     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3336     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3337     hr = IDirect3DDevice9_BeginScene(device);
3338     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3339     if(SUCCEEDED(hr))
3340     {
3341         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3342         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3343         hr = IDirect3DDevice9_EndScene(device);
3344         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3345     }
3346     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3347
3348     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3349     color = getPixelColor(device, 63, 46);
3350     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3351     color = getPixelColor(device, 66, 46);
3352     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3353     color = getPixelColor(device, 63, 49);
3354     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3355     color = getPixelColor(device, 66, 49);
3356     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3357
3358     color = getPixelColor(device, 578, 46);
3359     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3360     color = getPixelColor(device, 575, 46);
3361     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3362     color = getPixelColor(device, 578, 49);
3363     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3364     color = getPixelColor(device, 575, 49);
3365     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3366
3367     color = getPixelColor(device, 63, 430);
3368     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3369     color = getPixelColor(device, 63, 433);
3370     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3371     color = getPixelColor(device, 66, 433);
3372     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3373     color = getPixelColor(device, 66, 430);
3374     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3375
3376     color = getPixelColor(device, 578, 430);
3377     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3378     color = getPixelColor(device, 578, 433);
3379     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3380     color = getPixelColor(device, 575, 433);
3381     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3382     color = getPixelColor(device, 575, 430);
3383     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3384
3385     /* Cleanup */
3386     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3387     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3388     IDirect3DPixelShader9_Release(shader);
3389 }
3390
3391 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3392 {
3393     IDirect3D9 *d3d9;
3394     HRESULT hr;
3395     IDirect3DTexture9 *texture;
3396     IDirect3DPixelShader9 *shader;
3397     IDirect3DPixelShader9 *shader2;
3398     D3DLOCKED_RECT lr;
3399     DWORD color;
3400     DWORD shader_code[] = {
3401         0xffff0101,                             /* ps_1_1       */
3402         0x00000042, 0xb00f0000,                 /* tex t0       */
3403         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3404         0x0000ffff                              /* end          */
3405     };
3406     DWORD shader_code2[] = {
3407         0xffff0101,                             /* ps_1_1       */
3408         0x00000042, 0xb00f0000,                 /* tex t0       */
3409         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3410         0x0000ffff                              /* end          */
3411     };
3412
3413     float quad[] = {
3414        -1.0,   -1.0,   0.1,     0.5,    0.5,
3415         1.0,   -1.0,   0.1,     0.5,    0.5,
3416        -1.0,    1.0,   0.1,     0.5,    0.5,
3417         1.0,    1.0,   0.1,     0.5,    0.5,
3418     };
3419
3420     memset(&lr, 0, sizeof(lr));
3421     IDirect3DDevice9_GetDirect3D(device, &d3d9);
3422     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3423                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
3424     IDirect3D9_Release(d3d9);
3425     if(FAILED(hr)) {
3426         skip("No D3DFMT_X8L8V8U8 support\n");
3427     };
3428
3429     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3430     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3431
3432     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
3433     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
3434     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3435     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
3436     *((DWORD *) lr.pBits) = 0x11ca3141;
3437     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3438     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
3439
3440     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3441     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3442     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
3443     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3444
3445     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3446     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
3447     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3448     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3449     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3450     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3451
3452     hr = IDirect3DDevice9_BeginScene(device);
3453     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3454     if(SUCCEEDED(hr))
3455     {
3456         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3457         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3458
3459         hr = IDirect3DDevice9_EndScene(device);
3460         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3461     }
3462     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3463     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3464     color = getPixelColor(device, 578, 430);
3465     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
3466        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
3467
3468     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
3469     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3470     hr = IDirect3DDevice9_BeginScene(device);
3471     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3472     if(SUCCEEDED(hr))
3473     {
3474         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3475         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3476
3477         hr = IDirect3DDevice9_EndScene(device);
3478         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3479     }
3480     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3481     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3482     color = getPixelColor(device, 578, 430);
3483     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
3484
3485     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3486     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3487     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3489     IDirect3DPixelShader9_Release(shader);
3490     IDirect3DPixelShader9_Release(shader2);
3491     IDirect3DTexture9_Release(texture);
3492 }
3493
3494 static void autogen_mipmap_test(IDirect3DDevice9 *device)
3495 {
3496     HRESULT hr;
3497     IDirect3D9 *d3d;
3498     IDirect3DTexture9 *texture = NULL;
3499     IDirect3DSurface9 *surface;
3500     DWORD color;
3501     const RECT r1 = {256, 256, 512, 512};
3502     const RECT r2 = {512, 256, 768, 512};
3503     const RECT r3 = {256, 512, 512, 768};
3504     const RECT r4 = {512, 512, 768, 768};
3505     unsigned int x, y;
3506     D3DLOCKED_RECT lr;
3507     memset(&lr, 0, sizeof(lr));
3508
3509     IDirect3DDevice9_GetDirect3D(device, &d3d);
3510     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3511        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
3512         skip("No autogenmipmap support\n");
3513         IDirect3D9_Release(d3d);
3514         return;
3515     }
3516     IDirect3D9_Release(d3d);
3517
3518     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3519     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3520
3521     /* Make the mipmap big, so that a smaller mipmap is used
3522      */
3523     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
3524                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
3525     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3526
3527     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3528     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
3529     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
3530     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
3531     for(y = 0; y < 1024; y++) {
3532         for(x = 0; x < 1024; x++) {
3533             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
3534             POINT pt;
3535
3536             pt.x = x;
3537             pt.y = y;
3538             if(PtInRect(&r1, pt)) {
3539                 *dst = 0xffff0000;
3540             } else if(PtInRect(&r2, pt)) {
3541                 *dst = 0xff00ff00;
3542             } else if(PtInRect(&r3, pt)) {
3543                 *dst = 0xff0000ff;
3544             } else if(PtInRect(&r4, pt)) {
3545                 *dst = 0xff000000;
3546             } else {
3547                 *dst = 0xffffffff;
3548             }
3549         }
3550     }
3551     hr = IDirect3DSurface9_UnlockRect(surface);
3552     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3553     IDirect3DSurface9_Release(surface);
3554
3555     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3556     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3557     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3558     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3559
3560     hr = IDirect3DDevice9_BeginScene(device);
3561     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3562     if(SUCCEEDED(hr)) {
3563         const float quad[] =  {
3564            -0.5,   -0.5,    0.1,    0.0,    0.0,
3565            -0.5,    0.5,    0.1,    0.0,    1.0,
3566             0.5,   -0.5,    0.1,    1.0,    0.0,
3567             0.5,    0.5,    0.1,    1.0,    1.0
3568         };
3569
3570         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3573         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3574         hr = IDirect3DDevice9_EndScene(device);
3575         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3576     }
3577     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3578     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3579     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3580     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3581     IDirect3DTexture9_Release(texture);
3582
3583     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3584     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3585     color = getPixelColor(device, 200, 200);
3586     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
3587     color = getPixelColor(device, 280, 200);
3588     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
3589     color = getPixelColor(device, 360, 200);
3590     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
3591     color = getPixelColor(device, 440, 200);
3592     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3593     color = getPixelColor(device, 200, 270);
3594     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
3595     color = getPixelColor(device, 280, 270);
3596     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
3597     color = getPixelColor(device, 360, 270);
3598     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
3599     color = getPixelColor(device, 440, 270);
3600     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3601 }
3602
3603 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
3604 {
3605     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
3606     IDirect3DVertexDeclaration9 *decl;
3607     HRESULT hr;
3608     DWORD color;
3609     DWORD shader_code_11[] =  {
3610         0xfffe0101,                                         /* vs_1_1           */
3611         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3612         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3613         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3614         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3615         0x0000ffff                                          /* end              */
3616     };
3617     DWORD shader_code_11_2[] =  {
3618         0xfffe0101,                                         /* vs_1_1           */
3619         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
3620         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
3621         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3622         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3623         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3624         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3625         0x0000ffff                                          /* end              */
3626     };
3627     DWORD shader_code_20[] =  {
3628         0xfffe0200,                                         /* vs_2_0           */
3629         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3630         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3631         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3632         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3633         0x0000ffff                                          /* end              */
3634     };
3635     DWORD shader_code_20_2[] =  {
3636         0xfffe0200,                                         /* vs_2_0           */
3637         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
3638         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
3639         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3640         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3641         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3642         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3643         0x0000ffff                                          /* end              */
3644     };
3645     static const D3DVERTEXELEMENT9 decl_elements[] = {
3646         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3647         D3DDECL_END()
3648     };
3649     float quad1[] = {
3650         -1.0,   -1.0,   0.1,
3651          0.0,   -1.0,   0.1,
3652         -1.0,    0.0,   0.1,
3653          0.0,    0.0,   0.1
3654     };
3655     float quad2[] = {
3656          0.0,   -1.0,   0.1,
3657          1.0,   -1.0,   0.1,
3658          0.0,    0.0,   0.1,
3659          1.0,    0.0,   0.1
3660     };
3661     float quad3[] = {
3662          0.0,    0.0,   0.1,
3663          1.0,    0.0,   0.1,
3664          0.0,    1.0,   0.1,
3665          1.0,    1.0,   0.1
3666     };
3667     float quad4[] = {
3668         -1.0,    0.0,   0.1,
3669          0.0,    0.0,   0.1,
3670         -1.0,    1.0,   0.1,
3671          0.0,    1.0,   0.1
3672     };
3673     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3674     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3675
3676     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3677     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3678
3679     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
3680     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3681     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
3682     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3683     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
3684     if(FAILED(hr)) shader_20 = NULL;
3685     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
3686     if(FAILED(hr)) shader_20_2 = NULL;
3687     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3688     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3689
3690     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
3691     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3692     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
3693     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3694     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3695     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3696
3697     hr = IDirect3DDevice9_BeginScene(device);
3698     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3699     if(SUCCEEDED(hr))
3700     {
3701         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
3702         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3703         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3704         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3705
3706         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
3707         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3709         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3710
3711         if(shader_20) {
3712             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
3713             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3714             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3715             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3716         }
3717
3718         if(shader_20_2) {
3719             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
3720             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3721             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3722             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3723         }
3724
3725         hr = IDirect3DDevice9_EndScene(device);
3726         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3727     }
3728     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3729     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3730
3731     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3733     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3734     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3735
3736     color = getPixelColor(device, 160, 360);
3737     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3738        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
3739     color = getPixelColor(device, 480, 360);
3740     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3741        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
3742     if(shader_20) {
3743         color = getPixelColor(device, 160, 120);
3744         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3745            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
3746     }
3747     if(shader_20_2) {
3748         color = getPixelColor(device, 480, 120);
3749         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3750            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3751     }
3752
3753     IDirect3DVertexDeclaration9_Release(decl);
3754     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
3755     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
3756     IDirect3DVertexShader9_Release(shader_11_2);
3757     IDirect3DVertexShader9_Release(shader_11);
3758 }
3759
3760 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
3761 {
3762     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
3763     HRESULT hr;
3764     DWORD color;
3765     DWORD shader_code_11[] =  {
3766         0xffff0101,                                         /* ps_1_1           */
3767         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3768         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3769         0x0000ffff                                          /* end              */
3770     };
3771     DWORD shader_code_12[] =  {
3772         0xffff0102,                                         /* ps_1_2           */
3773         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3774         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3775         0x0000ffff                                          /* end              */
3776     };
3777     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
3778      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
3779      * During development of this test, 1.3 shaders were verified too
3780      */
3781     DWORD shader_code_14[] =  {
3782         0xffff0104,                                         /* ps_1_4           */
3783         /* Try to make one constant local. It gets clamped too, although the binary contains
3784          * the bigger numbers
3785          */
3786         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
3787         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3788         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3789         0x0000ffff                                          /* end              */
3790     };
3791     DWORD shader_code_20[] =  {
3792         0xffff0200,                                         /* ps_2_0           */
3793         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3794         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3795         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
3796         0x0000ffff                                          /* end              */
3797     };
3798     float quad1[] = {
3799         -1.0,   -1.0,   0.1,
3800          0.0,   -1.0,   0.1,
3801         -1.0,    0.0,   0.1,
3802          0.0,    0.0,   0.1
3803     };
3804     float quad2[] = {
3805          0.0,   -1.0,   0.1,
3806          1.0,   -1.0,   0.1,
3807          0.0,    0.0,   0.1,
3808          1.0,    0.0,   0.1
3809     };
3810     float quad3[] = {
3811          0.0,    0.0,   0.1,
3812          1.0,    0.0,   0.1,
3813          0.0,    1.0,   0.1,
3814          1.0,    1.0,   0.1
3815     };
3816     float quad4[] = {
3817         -1.0,    0.0,   0.1,
3818          0.0,    0.0,   0.1,
3819         -1.0,    1.0,   0.1,
3820          0.0,    1.0,   0.1
3821     };
3822     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3823     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3824
3825     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3826     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3827
3828     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3829     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3830     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3831     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3832     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3833     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3834     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
3835     if(FAILED(hr)) shader_20 = NULL;
3836
3837     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3838     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3839     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3840     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3841     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3842     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3843
3844     hr = IDirect3DDevice9_BeginScene(device);
3845     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3846     if(SUCCEEDED(hr))
3847     {
3848         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3849         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3850         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3851         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3852
3853         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3854         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3855         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3856         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3857
3858         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3859         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3860         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3861         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3862
3863         if(shader_20) {
3864             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
3865             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3866             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3867             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3868         }
3869
3870         hr = IDirect3DDevice9_EndScene(device);
3871         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3872     }
3873     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3874     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3875
3876     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3877     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3878
3879     color = getPixelColor(device, 160, 360);
3880     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3881        "quad 1 has color %08x, expected 0x00808000\n", color);
3882     color = getPixelColor(device, 480, 360);
3883     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3884        "quad 2 has color %08x, expected 0x00808000\n", color);
3885     color = getPixelColor(device, 480, 120);
3886     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3887        "quad 3 has color %08x, expected 0x00808000\n", color);
3888     if(shader_20) {
3889         color = getPixelColor(device, 160, 120);
3890         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3891            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3892     }
3893
3894     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
3895     IDirect3DPixelShader9_Release(shader_14);
3896     IDirect3DPixelShader9_Release(shader_12);
3897     IDirect3DPixelShader9_Release(shader_11);
3898 }
3899
3900 static void cnd_test(IDirect3DDevice9 *device)
3901 {
3902     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
3903     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
3904     HRESULT hr;
3905     DWORD color;
3906     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
3907      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
3908      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
3909      */
3910     DWORD shader_code_11[] =  {
3911         0xffff0101,                                                                 /* ps_1_1               */
3912         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3913         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3914         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
3915         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3916         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3917         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3918         0x0000ffff                                                                  /* end                  */
3919     };
3920     DWORD shader_code_12[] =  {
3921         0xffff0102,                                                                 /* ps_1_2               */
3922         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3923         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3924         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3925         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3926         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3927         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3928         0x0000ffff                                                                  /* end                  */
3929     };
3930     DWORD shader_code_13[] =  {
3931         0xffff0103,                                                                 /* ps_1_3               */
3932         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3933         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3934         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3935         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
3936         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3937         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3938         0x0000ffff                                                                  /* end                  */
3939     };
3940     DWORD shader_code_14[] =  {
3941         0xffff0104,                                                                 /* ps_1_3               */
3942         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
3943         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
3944         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
3945         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
3946         0x0000ffff                                                                  /* end                  */
3947     };
3948
3949     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
3950      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
3951      * set by the compiler, it was added manually after compilation. It isn't always allowed,
3952      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
3953      * native CreatePixelShader returns an error.
3954      *
3955      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
3956      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
3957      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
3958      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
3959      */
3960     DWORD shader_code_11_coissue[] =  {
3961         0xffff0101,                                                             /* ps_1_1                   */
3962         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3963         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3964         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3965         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3966         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3967         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3968         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3969         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3970         /* 0x40000000 = D3DSI_COISSUE */
3971         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3972         0x0000ffff                                                              /* end                      */
3973     };
3974     DWORD shader_code_12_coissue[] =  {
3975         0xffff0102,                                                             /* ps_1_2                   */
3976         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3977         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3978         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3979         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3980         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3981         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3982         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3983         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3984         /* 0x40000000 = D3DSI_COISSUE */
3985         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3986         0x0000ffff                                                              /* end                      */
3987     };
3988     DWORD shader_code_13_coissue[] =  {
3989         0xffff0103,                                                             /* ps_1_3                   */
3990         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3991         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3992         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3993         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3994         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3995         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3996         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3997         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3998         /* 0x40000000 = D3DSI_COISSUE */
3999         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4000         0x0000ffff                                                              /* end                      */
4001     };
4002     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4003      * compare against 0.5
4004      */
4005     DWORD shader_code_14_coissue[] =  {
4006         0xffff0104,                                                             /* ps_1_4                   */
4007         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4008         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4009         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4010         /* 0x40000000 = D3DSI_COISSUE */
4011         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4012         0x0000ffff                                                              /* end                      */
4013     };
4014     float quad1[] = {
4015         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4016          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4017         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4018          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4019     };
4020     float quad2[] = {
4021          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4022          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4023          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4024          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4025     };
4026     float quad3[] = {
4027          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4028          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4029          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4030          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4031     };
4032     float quad4[] = {
4033         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4034          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4035         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4036          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4037     };
4038     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4039     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4040     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4041     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4042
4043     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4044     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4045
4046     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4047     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4048     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4049     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4050     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4051     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4052     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4053     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4054     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4055     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4056     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4057     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4058     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4059     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4060     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4061     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4062
4063     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4064     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4065     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4066     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4067     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4068     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4069
4070     hr = IDirect3DDevice9_BeginScene(device);
4071     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4072     if(SUCCEEDED(hr))
4073     {
4074         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4075         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4076         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4077         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4078
4079         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4080         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4081         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4082         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4083
4084         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4085         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4086         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4087         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4088
4089         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4090         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4091         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4092         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4093
4094         hr = IDirect3DDevice9_EndScene(device);
4095         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4096     }
4097     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4098     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4099
4100     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4101     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4102
4103     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4104     color = getPixelColor(device, 158, 118);
4105     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4106     color = getPixelColor(device, 162, 118);
4107     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4108     color = getPixelColor(device, 158, 122);
4109     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4110     color = getPixelColor(device, 162, 122);
4111     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4112
4113     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4114     color = getPixelColor(device, 158, 358);
4115     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4116     color = getPixelColor(device, 162, 358);
4117     ok(color == 0x00000000, "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4118     color = getPixelColor(device, 158, 362);
4119     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4120     color = getPixelColor(device, 162, 362);
4121     ok(color == 0x00000000, "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4122
4123     /* 1.2 shader */
4124     color = getPixelColor(device, 478, 358);
4125     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4126     color = getPixelColor(device, 482, 358);
4127     ok(color == 0x00000000, "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4128     color = getPixelColor(device, 478, 362);
4129     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4130     color = getPixelColor(device, 482, 362);
4131     ok(color == 0x00000000, "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4132
4133     /* 1.3 shader */
4134     color = getPixelColor(device, 478, 118);
4135     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4136     color = getPixelColor(device, 482, 118);
4137     ok(color == 0x00000000, "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4138     color = getPixelColor(device, 478, 122);
4139     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4140     color = getPixelColor(device, 482, 122);
4141     ok(color == 0x00000000, "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4142
4143     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4145     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4147     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4149
4150     hr = IDirect3DDevice9_BeginScene(device);
4151     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4152     if(SUCCEEDED(hr))
4153     {
4154         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4155         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4157         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4158
4159         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4160         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4162         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4163
4164         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4165         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4166         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4167         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4168
4169         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4170         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4171         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4172         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4173
4174         hr = IDirect3DDevice9_EndScene(device);
4175         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4176     }
4177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4178     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4179
4180     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4181      * that we swapped the values in c1 and c2 to make the other tests return some color
4182      */
4183     color = getPixelColor(device, 158, 118);
4184     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4185     color = getPixelColor(device, 162, 118);
4186     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4187     color = getPixelColor(device, 158, 122);
4188     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4189     color = getPixelColor(device, 162, 122);
4190     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4191
4192     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4193     color = getPixelColor(device, 158, 358);
4194     ok(color == 0x0000ff00, "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4195     color = getPixelColor(device, 162, 358);
4196     ok(color == 0x0000ff00, "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4197     color = getPixelColor(device, 158, 362);
4198     ok(color == 0x0000ff00, "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4199     color = getPixelColor(device, 162, 362);
4200     ok(color == 0x0000ff00, "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4201
4202     /* 1.2 shader */
4203     color = getPixelColor(device, 478, 358);
4204     ok(color == 0x0000ff00, "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4205     color = getPixelColor(device, 482, 358);
4206     ok(color == 0x0000ff00, "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4207     color = getPixelColor(device, 478, 362);
4208     ok(color == 0x0000ff00, "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4209     color = getPixelColor(device, 482, 362);
4210     ok(color == 0x0000ff00, "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4211
4212     /* 1.3 shader */
4213     color = getPixelColor(device, 478, 118);
4214     ok(color == 0x0000ff00, "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4215     color = getPixelColor(device, 482, 118);
4216     ok(color == 0x0000ff00, "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4217     color = getPixelColor(device, 478, 122);
4218     ok(color == 0x0000ff00, "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4219     color = getPixelColor(device, 482, 122);
4220     ok(color == 0x0000ff00, "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4221
4222     IDirect3DPixelShader9_Release(shader_14_coissue);
4223     IDirect3DPixelShader9_Release(shader_13_coissue);
4224     IDirect3DPixelShader9_Release(shader_12_coissue);
4225     IDirect3DPixelShader9_Release(shader_11_coissue);
4226     IDirect3DPixelShader9_Release(shader_14);
4227     IDirect3DPixelShader9_Release(shader_13);
4228     IDirect3DPixelShader9_Release(shader_12);
4229     IDirect3DPixelShader9_Release(shader_11);
4230 }
4231
4232 static void nested_loop_test(IDirect3DDevice9 *device) {
4233     const DWORD shader_code[] = {
4234         0xffff0300,                                                             /* ps_3_0               */
4235         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4236         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4237         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4238         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4239         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4240         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4241         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4242         0x0000001d,                                                             /* endloop              */
4243         0x0000001d,                                                             /* endloop              */
4244         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4245         0x0000ffff                                                              /* end                  */
4246     };
4247     IDirect3DPixelShader9 *shader;
4248     HRESULT hr;
4249     DWORD color;
4250     const float quad[] = {
4251         -1.0,   -1.0,   0.1,
4252          1.0,   -1.0,   0.1,
4253         -1.0,    1.0,   0.1,
4254          1.0,    1.0,   0.1
4255     };
4256
4257     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4258     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4259     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4260     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4261     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4262     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4263     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4264     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4265
4266     hr = IDirect3DDevice9_BeginScene(device);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4268     if(SUCCEEDED(hr))
4269     {
4270         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4271         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4272         hr = IDirect3DDevice9_EndScene(device);
4273         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4274     }
4275     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4276     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4277
4278     color = getPixelColor(device, 360, 240);
4279     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4280        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4281
4282     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4283     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4284     IDirect3DPixelShader9_Release(shader);
4285 }
4286
4287 struct varying_test_struct
4288 {
4289     const DWORD             *shader_code;
4290     IDirect3DPixelShader9   *shader;
4291     DWORD                   color, color_rhw;
4292     const char              *name;
4293     BOOL                    todo, todo_rhw;
4294 };
4295
4296 struct hugeVertex
4297 {
4298     float pos_x,        pos_y,      pos_z,      rhw;
4299     float weight_1,     weight_2,   weight_3,   weight_4;
4300     float index_1,      index_2,    index_3,    index_4;
4301     float normal_1,     normal_2,   normal_3,   normal_4;
4302     float fog_1,        fog_2,      fog_3,      fog_4;
4303     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
4304     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
4305     float binormal_1,   binormal_2, binormal_3, binormal_4;
4306     float depth_1,      depth_2,    depth_3,    depth_4;
4307     DWORD diffuse, specular;
4308 };
4309
4310 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
4311     /* dcl_position: fails to compile */
4312     const DWORD blendweight_code[] = {
4313         0xffff0300,                             /* ps_3_0                   */
4314         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
4315         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4316         0x0000ffff                              /* end                      */
4317     };
4318     const DWORD blendindices_code[] = {
4319         0xffff0300,                             /* ps_3_0                   */
4320         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
4321         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4322         0x0000ffff                              /* end                      */
4323     };
4324     const DWORD normal_code[] = {
4325         0xffff0300,                             /* ps_3_0                   */
4326         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
4327         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4328         0x0000ffff                              /* end                      */
4329     };
4330     /* psize: fails? */
4331     const DWORD texcoord0_code[] = {
4332         0xffff0300,                             /* ps_3_0                   */
4333         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
4334         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4335         0x0000ffff                              /* end                      */
4336     };
4337     const DWORD tangent_code[] = {
4338         0xffff0300,                             /* ps_3_0                   */
4339         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
4340         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4341         0x0000ffff                              /* end                      */
4342     };
4343     const DWORD binormal_code[] = {
4344         0xffff0300,                             /* ps_3_0                   */
4345         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
4346         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4347         0x0000ffff                              /* end                      */
4348     };
4349     /* tessfactor: fails */
4350     /* positiont: fails */
4351     const DWORD color_code[] = {
4352         0xffff0300,                             /* ps_3_0                   */
4353         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
4354         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4355         0x0000ffff                              /* end                      */
4356     };
4357     const DWORD fog_code[] = {
4358         0xffff0300,                             /* ps_3_0                   */
4359         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
4360         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4361         0x0000ffff                              /* end                      */
4362     };
4363     const DWORD depth_code[] = {
4364         0xffff0300,                             /* ps_3_0                   */
4365         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
4366         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4367         0x0000ffff                              /* end                      */
4368     };
4369     const DWORD specular_code[] = {
4370         0xffff0300,                             /* ps_3_0                   */
4371         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
4372         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4373         0x0000ffff                              /* end                      */
4374     };
4375     /* sample: fails */
4376
4377     struct varying_test_struct tests[] = {
4378        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
4379        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
4380        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
4381        /* Why does dx not forward the texcoord? */
4382        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
4383        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
4384        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
4385        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
4386        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
4387        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
4388        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
4389     };
4390     /* Declare a monster vertex type :-) */
4391     static const D3DVERTEXELEMENT9 decl_elements[] = {
4392         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
4393         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
4394         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
4395         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
4396         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
4397         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
4398         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
4399         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
4400         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
4401         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
4402         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
4403         D3DDECL_END()
4404     };
4405     static const D3DVERTEXELEMENT9 decl_elements2[] = {
4406         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
4407         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
4408         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
4409         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
4410         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
4411         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
4412         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
4413         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
4414         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
4415         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
4416         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
4417         D3DDECL_END()
4418     };
4419     struct hugeVertex data[4] = {
4420         {
4421             -1.0,   -1.0,   0.1,    1.0,
4422              0.1,    0.1,   0.1,    0.1,
4423              0.2,    0.2,   0.2,    0.2,
4424              0.3,    0.3,   0.3,    0.3,
4425              0.4,    0.4,   0.4,    0.4,
4426              0.50,   0.55,  0.55,   0.55,
4427              0.6,    0.6,   0.6,    0.7,
4428              0.7,    0.7,   0.7,    0.6,
4429              0.8,    0.8,   0.8,    0.8,
4430              0xe6e6e6e6, /* 0.9 * 256 */
4431              0x224488ff  /* Nothing special */
4432         },
4433         {
4434              1.0,   -1.0,   0.1,    1.0,
4435              0.1,    0.1,   0.1,    0.1,
4436              0.2,    0.2,   0.2,    0.2,
4437              0.3,    0.3,   0.3,    0.3,
4438              0.4,    0.4,   0.4,    0.4,
4439              0.50,   0.55,  0.55,   0.55,
4440              0.6,    0.6,   0.6,    0.7,
4441              0.7,    0.7,   0.7,    0.6,
4442              0.8,    0.8,   0.8,    0.8,
4443              0xe6e6e6e6, /* 0.9 * 256 */
4444              0x224488ff /* Nothing special */
4445         },
4446         {
4447             -1.0,    1.0,   0.1,    1.0,
4448              0.1,    0.1,   0.1,    0.1,
4449              0.2,    0.2,   0.2,    0.2,
4450              0.3,    0.3,   0.3,    0.3,
4451              0.4,    0.4,   0.4,    0.4,
4452              0.50,   0.55,  0.55,   0.55,
4453              0.6,    0.6,   0.6,    0.7,
4454              0.7,    0.7,   0.7,    0.6,
4455              0.8,    0.8,   0.8,    0.8,
4456              0xe6e6e6e6, /* 0.9 * 256 */
4457              0x224488ff /* Nothing special */
4458         },
4459         {
4460              1.0,    1.0,   0.1,    1.0,
4461              0.1,    0.1,   0.1,    0.1,
4462              0.2,    0.2,   0.2,    0.2,
4463              0.3,    0.3,   0.3,    0.3,
4464              0.4,    0.4,   0.4,    0.4,
4465              0.50,   0.55,  0.55,   0.55,
4466              0.6,    0.6,   0.6,    0.7,
4467              0.7,    0.7,   0.7,    0.6,
4468              0.8,    0.8,   0.8,    0.8,
4469              0xe6e6e6e6, /* 0.9 * 256 */
4470              0x224488ff /* Nothing special */
4471         },
4472     };
4473     struct hugeVertex data2[4];
4474     IDirect3DVertexDeclaration9 *decl;
4475     IDirect3DVertexDeclaration9 *decl2;
4476     HRESULT hr;
4477     unsigned int i;
4478     DWORD color, r, g, b, r_e, g_e, b_e;
4479
4480     memcpy(data2, data, sizeof(data2));
4481     data2[0].pos_x = 0;     data2[0].pos_y = 0;
4482     data2[1].pos_x = 640;   data2[1].pos_y = 0;
4483     data2[2].pos_x = 0;     data2[2].pos_y = 480;
4484     data2[3].pos_x = 640;   data2[3].pos_y = 480;
4485
4486     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4487     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4488     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4489     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4490     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4491     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4492
4493     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4494     {
4495         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
4496         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
4497            tests[i].name, DXGetErrorString9(hr));
4498     }
4499
4500     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4501     {
4502         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4503         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4504
4505         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4506         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4507
4508         hr = IDirect3DDevice9_BeginScene(device);
4509         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4510         if(SUCCEEDED(hr))
4511         {
4512             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
4513             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4514             hr = IDirect3DDevice9_EndScene(device);
4515             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4516         }
4517         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4518         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4519
4520         color = getPixelColor(device, 360, 240);
4521         r = color & 0x00ff0000 >> 16;
4522         g = color & 0x0000ff00 >>  8;
4523         b = color & 0x000000ff;
4524         r_e = tests[i].color & 0x00ff0000 >> 16;
4525         g_e = tests[i].color & 0x0000ff00 >>  8;
4526         b_e = tests[i].color & 0x000000ff;
4527
4528         if(tests[i].todo) {
4529             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4530                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4531                          tests[i].name, color, tests[i].color);
4532         } else {
4533             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4534                "Test %s returned color 0x%08x, expected 0x%08x\n",
4535                tests[i].name, color, tests[i].color);
4536         }
4537     }
4538
4539     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4541     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4542     {
4543         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4544         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4545
4546         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4547         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4548
4549         hr = IDirect3DDevice9_BeginScene(device);
4550         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4551         if(SUCCEEDED(hr))
4552         {
4553             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
4554             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4555             hr = IDirect3DDevice9_EndScene(device);
4556             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4557         }
4558         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4559         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4560
4561         color = getPixelColor(device, 360, 240);
4562         r = color & 0x00ff0000 >> 16;
4563         g = color & 0x0000ff00 >>  8;
4564         b = color & 0x000000ff;
4565         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
4566         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
4567         b_e = tests[i].color_rhw & 0x000000ff;
4568
4569         if(tests[i].todo_rhw) {
4570             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
4571              * pipeline
4572              */
4573             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4574                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4575                          tests[i].name, color, tests[i].color_rhw);
4576         } else {
4577             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4578                "Test %s returned color 0x%08x, expected 0x%08x\n",
4579                tests[i].name, color, tests[i].color_rhw);
4580         }
4581     }
4582
4583     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4584     {
4585         IDirect3DPixelShader9_Release(tests[i].shader);
4586     }
4587
4588     IDirect3DVertexDeclaration9_Release(decl2);
4589     IDirect3DVertexDeclaration9_Release(decl);
4590 }
4591
4592 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
4593     static const DWORD ps_code[] = {
4594     0xffff0300,                                                             /* ps_3_0                       */
4595     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
4596     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
4597     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
4598     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
4599     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
4600     0x0200001f, 0x80000003, 0x900f0006,
4601     0x0200001f, 0x80000006, 0x900f0007,
4602     0x0200001f, 0x80000001, 0x900f0008,
4603     0x0200001f, 0x8000000c, 0x900f0009,
4604
4605     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4606     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
4607     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
4608     0x0000001d,                                                             /* endloop                      */
4609     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4610     0x0000ffff                                                              /* end                          */
4611     };
4612     static const DWORD vs_1_code[] = {
4613     0xfffe0101,                                                             /* vs_1_1                       */
4614     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4615     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
4616     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
4617     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
4618     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4619     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
4620     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
4621     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
4622     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
4623     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
4624     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
4625     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
4626     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
4627     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
4628     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
4629     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
4630     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
4631     0x0000ffff
4632     };
4633     DWORD vs_2_code[] = {
4634     0xfffe0200,                                                             /* vs_2_0                       */
4635     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4636     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
4637     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0   */
4638     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0   */
4639     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4640     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
4641     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
4642     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
4643     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
4644     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
4645     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
4646     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
4647     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
4648     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
4649     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
4650     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
4651     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
4652     0x0000ffff                                                              /* end                          */
4653     };
4654     /* TODO: Define normal, tangent, blendweight and depth here */
4655     static const DWORD vs_3_code[] = {
4656     0xfffe0300,                                                             /* vs_3_0                       */
4657     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4658     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
4659     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
4660     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
4661     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
4662     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
4663     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
4664     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
4665     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4666     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
4667     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
4668     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
4669     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
4670     0x0000ffff                                                              /* end                          */
4671     };
4672     float quad1[] =  {
4673         -1.0,   -1.0,   0.1,
4674          0.0,   -1.0,   0.1,
4675         -1.0,    0.0,   0.1,
4676          0.0,    0.0,   0.1
4677     };
4678     float quad2[] =  {
4679          0.0,   -1.0,   0.1,
4680          1.0,   -1.0,   0.1,
4681          0.0,    0.0,   0.1,
4682          1.0,    0.0,   0.1
4683     };
4684     float quad3[] =  {
4685         -1.0,    0.0,   0.1,
4686          0.0,    0.0,   0.1,
4687         -1.0,    1.0,   0.1,
4688          0.0,    1.0,   0.1
4689     };
4690
4691     HRESULT hr;
4692     DWORD color;
4693     IDirect3DPixelShader9 *pixelshader = NULL;
4694     IDirect3DVertexShader9 *vs_1_shader = NULL;
4695     IDirect3DVertexShader9 *vs_2_shader = NULL;
4696     IDirect3DVertexShader9 *vs_3_shader = NULL;
4697
4698     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
4699
4700     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
4701     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4702     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
4703     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4704     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
4705     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4706     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
4707     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4708     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
4709     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4710     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4711
4712     hr = IDirect3DDevice9_BeginScene(device);
4713     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4714     if(SUCCEEDED(hr))
4715     {
4716         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
4717         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4719         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4720
4721         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
4722         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4723         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4724         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4725
4726         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
4727         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4728         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4729         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4730
4731         hr = IDirect3DDevice9_EndScene(device);
4732         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4733     }
4734     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4735     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4736
4737     color = getPixelColor(device, 160, 120);
4738     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4739        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
4740        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4741        "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
4742     color = getPixelColor(device, 160, 360);
4743     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4744        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4745        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4746        "vs_1_1 returned color 0x%08x, expected 0x00808080\n", color);
4747     color = getPixelColor(device, 480, 360);
4748     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4749        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4750        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4751        "vs_2_0 returned color 0x%08x, expected 0x00000000\n", color);
4752
4753     /* cleanup */
4754     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4755     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4756     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4758     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
4759     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
4760     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
4761     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
4762 }
4763
4764 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
4765     static const DWORD vs_code[] = {
4766     0xfffe0300,                                                             /* vs_3_0                       */
4767     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4768     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
4769     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
4770     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
4771     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
4772     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
4773     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
4774     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
4775     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
4776     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
4777     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
4778     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
4779     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
4780
4781     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
4782     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
4783     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
4784     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
4785     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
4786     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
4787     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
4788     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
4789     0x0000ffff                                                              /* end                          */
4790     };
4791     static const DWORD ps_1_code[] = {
4792     0xffff0104,                                                             /* ps_1_4                       */
4793     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
4794     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
4795     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
4796     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
4797     0x0000ffff                                                              /* end                          */
4798     };
4799     static const DWORD ps_2_code[] = {
4800     0xffff0200,                                                             /* ps_2_0                       */
4801     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
4802     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
4803     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
4804
4805     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
4806     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
4807     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4808     0x0000ffff                                                              /* end                          */
4809     };
4810     static const DWORD ps_3_code[] = {
4811     0xffff0300,                                                             /* ps_3_0                       */
4812     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
4813     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
4814     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
4815
4816     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
4817     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
4818     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
4819     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4820     0x0000ffff                                                              /* end                          */
4821     };
4822
4823     float quad1[] =  {
4824         -1.0,   -1.0,   0.1,
4825          0.0,   -1.0,   0.1,
4826         -1.0,    0.0,   0.1,
4827          0.0,    0.0,   0.1
4828     };
4829     float quad2[] =  {
4830          0.0,   -1.0,   0.1,
4831          1.0,   -1.0,   0.1,
4832          0.0,    0.0,   0.1,
4833          1.0,    0.0,   0.1
4834     };
4835     float quad3[] =  {
4836         -1.0,    0.0,   0.1,
4837          0.0,    0.0,   0.1,
4838         -1.0,    1.0,   0.1,
4839          0.0,    1.0,   0.1
4840     };
4841     float quad4[] =  {
4842          0.0,    0.0,   0.1,
4843          1.0,    0.0,   0.1,
4844          0.0,    1.0,   0.1,
4845          1.0,    1.0,   0.1
4846     };
4847
4848     HRESULT hr;
4849     DWORD color;
4850     IDirect3DVertexShader9 *vertexshader = NULL;
4851     IDirect3DPixelShader9 *ps_1_shader = NULL;
4852     IDirect3DPixelShader9 *ps_2_shader = NULL;
4853     IDirect3DPixelShader9 *ps_3_shader = NULL;
4854     IDirect3DTexture9 *texture = NULL;
4855     D3DLOCKED_RECT lr;
4856     unsigned int x, y;
4857
4858     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4859
4860     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
4861     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4862     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4863     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
4864     for(y = 0; y < 512; y++) {
4865         for(x = 0; x < 512; x++) {
4866             double r_f = (double) x / (double) 512;
4867             double g_f = (double) y / (double) 512;
4868             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
4869             unsigned short r = (unsigned short) (r_f * 65535.0);
4870             unsigned short g = (unsigned short) (g_f * 65535.0);
4871             dst[0] = r;
4872             dst[1] = g;
4873             dst[2] = 0;
4874             dst[3] = 65535;
4875         }
4876     }
4877     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4878     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4879
4880     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
4881     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4882     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
4883     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4884     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
4885     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4886     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
4887     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4888     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
4889     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4890     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4891
4892     hr = IDirect3DDevice9_BeginScene(device);
4893     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4894     if(SUCCEEDED(hr))
4895     {
4896         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
4897         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4898         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4899         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4900
4901         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
4902         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4903         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4904         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4905
4906         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
4907         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4908         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4909         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4910
4911         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4912         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4913         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4914         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4915         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4916         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
4917         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4918         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
4919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
4920         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4921
4922         hr = IDirect3DDevice9_EndScene(device);
4923         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4924     }
4925     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4926     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4927
4928     color = getPixelColor(device, 160, 120);
4929     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
4930        (color & 0x0000ff00) == 0x0000ff00 &&
4931        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
4932        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
4933     color = getPixelColor(device, 160, 360);
4934     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4935        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
4936        (color & 0x000000ff) == 0x00000000,
4937        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
4938     color = getPixelColor(device, 480, 360);
4939     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4940        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4941        (color & 0x000000ff) == 0x00000000,
4942        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
4943     color = getPixelColor(device, 480, 160);
4944     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4945        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4946        (color & 0x000000ff) == 0x00000000,
4947        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
4948
4949     /* cleanup */
4950     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4951     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4952     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4953     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4954     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4956     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
4957     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
4958     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
4959     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
4960     if(texture) IDirect3DTexture9_Release(texture);
4961 }
4962
4963 void test_compare_instructions(IDirect3DDevice9 *device)
4964 {
4965     DWORD shader_sge_vec_code[] = {
4966         0xfffe0101,                                         /* vs_1_1                   */
4967         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4968         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4969         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4970         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
4971         0x0000ffff                                          /* end                      */
4972     };
4973     DWORD shader_slt_vec_code[] = {
4974         0xfffe0101,                                         /* vs_1_1                   */
4975         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4976         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4977         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4978         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
4979         0x0000ffff                                          /* end                      */
4980     };
4981     DWORD shader_sge_scalar_code[] = {
4982         0xfffe0101,                                         /* vs_1_1                   */
4983         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4984         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4985         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4986         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
4987         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
4988         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
4989         0x0000ffff                                          /* end                      */
4990     };
4991     DWORD shader_slt_scalar_code[] = {
4992         0xfffe0101,                                         /* vs_1_1                   */
4993         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4994         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4995         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4996         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
4997         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
4998         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
4999         0x0000ffff                                          /* end                      */
5000     };
5001     IDirect3DVertexShader9 *shader_sge_vec;
5002     IDirect3DVertexShader9 *shader_slt_vec;
5003     IDirect3DVertexShader9 *shader_sge_scalar;
5004     IDirect3DVertexShader9 *shader_slt_scalar;
5005     HRESULT hr, color;
5006     float quad1[] =  {
5007         -1.0,   -1.0,   0.1,
5008          0.0,   -1.0,   0.1,
5009         -1.0,    0.0,   0.1,
5010          0.0,    0.0,   0.1
5011     };
5012     float quad2[] =  {
5013          0.0,   -1.0,   0.1,
5014          1.0,   -1.0,   0.1,
5015          0.0,    0.0,   0.1,
5016          1.0,    0.0,   0.1
5017     };
5018     float quad3[] =  {
5019         -1.0,    0.0,   0.1,
5020          0.0,    0.0,   0.1,
5021         -1.0,    1.0,   0.1,
5022          0.0,    1.0,   0.1
5023     };
5024     float quad4[] =  {
5025          0.0,    0.0,   0.1,
5026          1.0,    0.0,   0.1,
5027          0.0,    1.0,   0.1,
5028          1.0,    1.0,   0.1
5029     };
5030     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5031     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5032
5033     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5034
5035     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5036     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5037     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5038     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5039     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5040     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5041     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5042     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5043     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5044     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5045     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5046     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5047     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5049
5050     hr = IDirect3DDevice9_BeginScene(device);
5051     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5052     if(SUCCEEDED(hr))
5053     {
5054         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5055         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5056         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5057         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5058
5059         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5060         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5062         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5063
5064         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5065         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5066         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5067         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5068
5069         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5070         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5071
5072         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5073         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5074         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5075         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5076
5077         hr = IDirect3DDevice9_EndScene(device);
5078         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5079     }
5080
5081     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5082     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5083
5084     color = getPixelColor(device, 160, 360);
5085     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5086     color = getPixelColor(device, 480, 360);
5087     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5088     color = getPixelColor(device, 160, 120);
5089     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5090     color = getPixelColor(device, 480, 160);
5091     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5092
5093     IDirect3DVertexShader9_Release(shader_sge_vec);
5094     IDirect3DVertexShader9_Release(shader_slt_vec);
5095     IDirect3DVertexShader9_Release(shader_sge_scalar);
5096     IDirect3DVertexShader9_Release(shader_slt_scalar);
5097 }
5098
5099 void test_vshader_input(IDirect3DDevice9 *device)
5100 {
5101     DWORD swapped_shader_code_3[] = {
5102         0xfffe0300,                                         /* vs_3_0               */
5103         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5104         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5105         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5106         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5107         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5108         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5109         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5110         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5111         0x0000ffff                                          /* end                  */
5112     };
5113     DWORD swapped_shader_code_1[] = {
5114         0xfffe0101,                                         /* vs_1_1               */
5115         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5116         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5117         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5118         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5119         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5120         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5121         0x0000ffff                                          /* end                  */
5122     };
5123     DWORD swapped_shader_code_2[] = {
5124         0xfffe0200,                                         /* vs_2_0               */
5125         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5126         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5127         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5128         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5129         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5130         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5131         0x0000ffff                                          /* end                  */
5132     };
5133     DWORD texcoord_color_shader_code_3[] = {
5134         0xfffe0300,                                         /* vs_3_0               */
5135         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5136         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5137         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5138         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5139         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5140         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5141         0x0000ffff                                          /* end                  */
5142     };
5143     DWORD texcoord_color_shader_code_2[] = {
5144         0xfffe0200,                                         /* vs_2_0               */
5145         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5146         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5147         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5148         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5149         0x0000ffff                                          /* end                  */
5150     };
5151     DWORD texcoord_color_shader_code_1[] = {
5152         0xfffe0101,                                         /* vs_1_1               */
5153         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5154         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5155         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5156         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5157         0x0000ffff                                          /* end                  */
5158     };
5159     DWORD color_color_shader_code_3[] = {
5160         0xfffe0300,                                         /* vs_3_0               */
5161         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5162         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5163         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5164         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5165         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5166         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5167         0x0000ffff                                          /* end                  */
5168     };
5169     DWORD color_color_shader_code_2[] = {
5170         0xfffe0200,                                         /* vs_2_0               */
5171         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5172         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5173         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5174         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5175         0x0000ffff                                          /* end                  */
5176     };
5177     DWORD color_color_shader_code_1[] = {
5178         0xfffe0101,                                         /* vs_1_1               */
5179         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5180         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5181         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5182         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5183         0x0000ffff                                          /* end                  */
5184     };
5185     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5186     HRESULT hr;
5187     DWORD color, r, g, b;
5188     float quad1[] =  {
5189         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5190          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5191         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5192          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5193     };
5194     float quad2[] =  {
5195          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5196          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5197          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5198          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5199     };
5200     float quad3[] =  {
5201         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5202          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5203         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5204          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5205     };
5206     float quad4[] =  {
5207          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5208          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5209          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5210          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5211     };
5212     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5213         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5214         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5215         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5216         D3DDECL_END()
5217     };
5218     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5219         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5220         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5221         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5222         D3DDECL_END()
5223     };
5224     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5225         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5226         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5227         D3DDECL_END()
5228     };
5229     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5230         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5231         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5232         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5233         D3DDECL_END()
5234     };
5235     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5236         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5237         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5238         D3DDECL_END()
5239     };
5240     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5241         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5242         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5243         D3DDECL_END()
5244     };
5245     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5246         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5247         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5248         D3DDECL_END()
5249     };
5250     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5251         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5252         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5253         D3DDECL_END()
5254     };
5255     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5256     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5257     unsigned int i;
5258     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5259     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5260
5261     struct vertex quad1_color[] =  {
5262        {-1.0,   -1.0,   0.1,    0x00ff8040},
5263        { 0.0,   -1.0,   0.1,    0x00ff8040},
5264        {-1.0,    0.0,   0.1,    0x00ff8040},
5265        { 0.0,    0.0,   0.1,    0x00ff8040}
5266     };
5267     struct vertex quad2_color[] =  {
5268        { 0.0,   -1.0,   0.1,    0x00ff8040},
5269        { 1.0,   -1.0,   0.1,    0x00ff8040},
5270        { 0.0,    0.0,   0.1,    0x00ff8040},
5271        { 1.0,    0.0,   0.1,    0x00ff8040}
5272     };
5273     struct vertex quad3_color[] =  {
5274        {-1.0,    0.0,   0.1,    0x00ff8040},
5275        { 0.0,    0.0,   0.1,    0x00ff8040},
5276        {-1.0,    1.0,   0.1,    0x00ff8040},
5277        { 0.0,    1.0,   0.1,    0x00ff8040}
5278     };
5279     float quad4_color[] =  {
5280          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5281          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5282          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5283          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5284     };
5285
5286     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
5287     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5288     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
5289     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5290     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
5291     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5292     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
5293     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5294
5295     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
5296     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5297     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
5298     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5299     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
5300     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5301     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
5302     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5303
5304     for(i = 1; i <= 3; i++) {
5305         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5306         if(i == 3) {
5307             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
5308             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5309         } else if(i == 2){
5310             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
5311             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5312         } else if(i == 1) {
5313             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
5314             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5315         }
5316
5317         hr = IDirect3DDevice9_BeginScene(device);
5318         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5319         if(SUCCEEDED(hr))
5320         {
5321             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5322             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5323
5324             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5325             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5326             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
5327             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5328
5329             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5330             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5331             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
5332             if(i == 3 || i == 2) {
5333                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5334             } else if(i == 1) {
5335                 /* Succeeds or fails, depending on SW or HW vertex processing */
5336                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5337             }
5338
5339             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
5340             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5341             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
5342             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5343
5344             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
5345             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5346             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
5347             if(i == 3 || i == 2) {
5348                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5349             } else if(i == 1) {
5350                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
5351             }
5352
5353             hr = IDirect3DDevice9_EndScene(device);
5354             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5355         }
5356
5357         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5358         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5359
5360         if(i == 3 || i == 2) {
5361             color = getPixelColor(device, 160, 360);
5362             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5363                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5364
5365             /* The last value of the read but undefined stream is used */
5366             color = getPixelColor(device, 480, 360);
5367             ok(color == 0x00FFFF00, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5368             color = getPixelColor(device, 160, 120);
5369             ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081,
5370                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5371
5372             color = getPixelColor(device, 480, 160);
5373             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5374         } else if(i == 1) {
5375             color = getPixelColor(device, 160, 360);
5376             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5377                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5378             color = getPixelColor(device, 480, 360);
5379             /* Accept the clear color as well in this case, since SW VP returns an error */
5380             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5381             color = getPixelColor(device, 160, 120);
5382             ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
5383                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5384             color = getPixelColor(device, 480, 160);
5385             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5386         }
5387
5388         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
5389         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5390
5391         /* Now find out if the whole streams are re-read, or just the last active value for the
5392          * vertices is used.
5393          */
5394         hr = IDirect3DDevice9_BeginScene(device);
5395         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5396         if(SUCCEEDED(hr))
5397         {
5398             float quad1_modified[] =  {
5399                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5400                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
5401                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
5402                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
5403             };
5404             float quad2_modified[] =  {
5405                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5406                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5407                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5408                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5409             };
5410
5411             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5412             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5413
5414             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5415             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5416             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
5417             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5418
5419             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5420             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5421             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
5422             if(i == 3 || i == 2) {
5423                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5424             } else if(i == 1) {
5425                 /* Succeeds or fails, depending on SW or HW vertex processing */
5426                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5427             }
5428
5429             hr = IDirect3DDevice9_EndScene(device);
5430             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5431         }
5432         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5433         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5434
5435         color = getPixelColor(device, 480, 360);
5436         /* vs_1_1 may fail, accept the clear color
5437          *
5438          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
5439          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
5440          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
5441          * refrast's result.
5442          *
5443          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
5444          */
5445         ok(color == 0x000000FF || color == 0x00808080,
5446            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF\n", color);
5447         color = getPixelColor(device, 160, 120);
5448
5449         IDirect3DDevice9_SetVertexShader(device, NULL);
5450         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5451
5452         IDirect3DVertexShader9_Release(swapped_shader);
5453     }
5454
5455     for(i = 1; i <= 3; i++) {
5456         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5457         if(i == 3) {
5458             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
5459             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5460             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
5461             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5462         } else if(i == 2){
5463             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
5464             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5465             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
5466             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5467         } else if(i == 1) {
5468             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
5469             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5470             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
5471             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5472         }
5473
5474         hr = IDirect3DDevice9_BeginScene(device);
5475         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5476         if(SUCCEEDED(hr))
5477         {
5478             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
5479             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5480             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
5481             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5482             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
5483             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5484
5485             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
5486             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5487
5488             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
5489             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5490             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
5491             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5492             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
5493             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5494
5495             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
5496             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5497             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
5498             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5499             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
5500             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5501
5502             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
5503             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5504             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
5505             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5506
5507             hr = IDirect3DDevice9_EndScene(device);
5508             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5509         }
5510         IDirect3DDevice9_SetVertexShader(device, NULL);
5511         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5512
5513         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5514         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5515
5516         color = getPixelColor(device, 160, 360);
5517         r = (color & 0x00ff0000) >> 16;
5518         g = (color & 0x0000ff00) >>  8;
5519         b = (color & 0x000000ff) >>  0;
5520         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5521            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
5522         color = getPixelColor(device, 480, 360);
5523         r = (color & 0x00ff0000) >> 16;
5524         g = (color & 0x0000ff00) >>  8;
5525         b = (color & 0x000000ff) >>  0;
5526         ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
5527            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
5528         color = getPixelColor(device, 160, 120);
5529         r = (color & 0x00ff0000) >> 16;
5530         g = (color & 0x0000ff00) >>  8;
5531         b = (color & 0x000000ff) >>  0;
5532         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5533            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
5534         color = getPixelColor(device, 480, 160);
5535         r = (color & 0x00ff0000) >> 16;
5536         g = (color & 0x0000ff00) >>  8;
5537         b = (color & 0x000000ff) >>  0;
5538         ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
5539            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
5540
5541         IDirect3DVertexShader9_Release(texcoord_color_shader);
5542         IDirect3DVertexShader9_Release(color_color_shader);
5543     }
5544
5545     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
5546     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
5547     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
5548     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
5549
5550     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
5551     IDirect3DVertexDeclaration9_Release(decl_color_color);
5552     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
5553     IDirect3DVertexDeclaration9_Release(decl_color_float);
5554 }
5555
5556 static void srgbtexture_test(IDirect3DDevice9 *device)
5557 {
5558     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
5559      * texture stage state to render a quad using that texture.  The resulting
5560      * color components should be 0x36 (~ 0.21), per this formula:
5561      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
5562      * This is true where srgb_color > 0.04045.
5563      */
5564     IDirect3D9 *d3d = NULL;
5565     HRESULT hr;
5566     LPDIRECT3DTEXTURE9 texture = NULL;
5567     LPDIRECT3DSURFACE9 surface = NULL;
5568     D3DLOCKED_RECT lr;
5569     DWORD color;
5570     float quad[] = {
5571         -1.0,       1.0,       0.0,     0.0,    0.0,
5572          1.0,       1.0,       0.0,     1.0,    0.0,
5573         -1.0,      -1.0,       0.0,     0.0,    1.0,
5574          1.0,      -1.0,       0.0,     1.0,    1.0,
5575     };
5576
5577
5578     memset(&lr, 0, sizeof(lr));
5579     IDirect3DDevice9_GetDirect3D(device, &d3d);
5580     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5581                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
5582                                     D3DFMT_A8R8G8B8) != D3D_OK) {
5583         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
5584         goto out;
5585     }
5586
5587     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
5588                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
5589                                         &texture, NULL);
5590     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
5591     if(!texture) {
5592         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
5593         goto out;
5594     }
5595     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5596     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
5597
5598     fill_surface(surface, 0xff7f7f7f);
5599     IDirect3DSurface9_Release(surface);
5600
5601     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5602     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5603     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5604     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
5605
5606     hr = IDirect3DDevice9_BeginScene(device);
5607     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
5608     if(SUCCEEDED(hr))
5609     {
5610         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
5611         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
5612
5613         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5614         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
5615
5616
5617         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5618         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
5619
5620         hr = IDirect3DDevice9_EndScene(device);
5621         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
5622     }
5623
5624     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5625     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
5626     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
5627     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
5628
5629     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5630     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5631
5632     color = getPixelColor(device, 320, 240);
5633     ok(color == 0x00363636, "srgb quad has color %08x, expected 0x00363636\n", color);
5634
5635 out:
5636     if(texture) IDirect3DTexture9_Release(texture);
5637     IDirect3D9_Release(d3d);
5638 }
5639
5640 static void shademode_test(IDirect3DDevice9 *device)
5641 {
5642     /* Render a quad and try all of the different fixed function shading models. */
5643     HRESULT hr;
5644     DWORD color0, color1;
5645     DWORD shademode = D3DSHADE_FLAT;
5646     DWORD primtype = D3DPT_TRIANGLESTRIP;
5647     LPVOID data = NULL;
5648     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
5649     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
5650     UINT i, j;
5651     struct vertex quad_strip[] =
5652     {
5653         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
5654         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
5655         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
5656         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
5657     };
5658     struct vertex quad_list[] =
5659     {
5660         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
5661         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
5662         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
5663
5664         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
5665         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
5666         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
5667     };
5668
5669     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
5670                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
5671     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
5672     if (FAILED(hr)) goto bail;
5673
5674     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
5675                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
5676     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
5677     if (FAILED(hr)) goto bail;
5678
5679     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5680     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5681
5682     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
5683     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
5684
5685     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
5686     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5687     memcpy(data, quad_strip, sizeof(quad_strip));
5688     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
5689     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
5690
5691     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
5692     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5693     memcpy(data, quad_list, sizeof(quad_list));
5694     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
5695     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
5696
5697     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
5698      * the color fixups we have to do for FLAT shading will be dependent on that. */
5699     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
5700     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5701
5702     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
5703     for (j=0; j<2; j++) {
5704
5705         /* Inner loop just changes the D3DRS_SHADEMODE */
5706         for (i=0; i<3; i++) {
5707             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5708             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5709
5710             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
5711             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5712
5713             hr = IDirect3DDevice9_BeginScene(device);
5714             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
5715             if(SUCCEEDED(hr))
5716             {
5717                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
5718                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
5719
5720                 hr = IDirect3DDevice9_EndScene(device);
5721                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
5722             }
5723
5724             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5725             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5726
5727             /* Sample two spots from the output */
5728             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
5729             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
5730             switch(shademode) {
5731                 case D3DSHADE_FLAT:
5732                     /* Should take the color of the first vertex of each triangle */
5733                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
5734                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
5735                     shademode = D3DSHADE_GOURAUD;
5736                     break;
5737                 case D3DSHADE_GOURAUD:
5738                     /* Should be an interpolated blend */
5739                     ok(color0 == 0x000dca28, "GOURAUD shading has color0 %08x, expected 0x000dca28\n", color0);
5740                     ok(color1 == 0x000d45c7, "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
5741                     shademode = D3DSHADE_PHONG;
5742                     break;
5743                 case D3DSHADE_PHONG:
5744                     /* Should be the same as GOURAUD, since no hardware implements this */
5745                     ok(color0 == 0x000dca28, "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
5746                     ok(color1 == 0x000d45c7, "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
5747                     break;
5748             }
5749         }
5750         /* Now, do it all over again with a TRIANGLELIST */
5751         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
5752         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5753         primtype = D3DPT_TRIANGLELIST;
5754         shademode = D3DSHADE_FLAT;
5755     }
5756
5757 bail:
5758     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
5759     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5760     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
5761     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5762
5763     if (vb_strip)
5764         IDirect3DVertexBuffer9_Release(vb_strip);
5765     if (vb_list)
5766         IDirect3DVertexBuffer9_Release(vb_list);
5767 }
5768
5769
5770 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
5771 {
5772     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
5773      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
5774      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
5775      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
5776      * 0.73
5777      *
5778      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
5779      * so use shaders for this task
5780      */
5781     IDirect3DPixelShader9 *pshader;
5782     IDirect3DVertexShader9 *vshader;
5783     IDirect3D9 *d3d;
5784     DWORD vshader_code[] = {
5785         0xfffe0101,                                                             /* vs_1_1                       */
5786         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5787         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
5788         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5789         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
5790         0x0000ffff                                                              /* end                          */
5791     };
5792     DWORD pshader_code[] = {
5793         0xffff0101,                                                             /* ps_1_1                       */
5794         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5795         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5796         0x0000ffff                                                              /* end                          */
5797     };
5798     const float quad[] = {
5799        -1.0,   -1.0,    0.1,
5800         1.0,   -1.0,    0.1,
5801        -1.0,    1.0,    0.1,
5802         1.0,    1.0,    0.1
5803     };
5804     HRESULT hr;
5805     DWORD color;
5806
5807     IDirect3DDevice9_GetDirect3D(device, &d3d);
5808     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5809                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
5810                                     D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
5811         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
5812         IDirect3D9_Release(d3d);
5813         return;
5814     }
5815     IDirect3D9_Release(d3d);
5816
5817     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5818     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5819
5820     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5821     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5822     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
5823     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5824     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
5825     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5826     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
5827     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5828     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
5829     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5830
5831     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5832     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5833     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
5834     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5835     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5836     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
5837     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5838     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5839     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
5840     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5841
5842     hr = IDirect3DDevice9_BeginScene(device);
5843     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5844     if(SUCCEEDED(hr)) {
5845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
5846         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5847
5848         hr = IDirect3DDevice9_EndScene(device);
5849         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5850     }
5851
5852     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5853     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5854     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5855     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5856     IDirect3DPixelShader9_Release(pshader);
5857     IDirect3DVertexShader9_Release(vshader);
5858
5859     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
5860     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5861     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
5862     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5863
5864     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5865     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5866     color = getPixelColor(device, 160, 360);
5867     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
5868        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
5869 }
5870
5871 static void alpha_test(IDirect3DDevice9 *device)
5872 {
5873     HRESULT hr;
5874     IDirect3DTexture9 *offscreenTexture;
5875     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
5876     DWORD color, red, green, blue;
5877
5878     struct vertex quad1[] =
5879     {
5880         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
5881         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
5882         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
5883         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
5884     };
5885     struct vertex quad2[] =
5886     {
5887         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
5888         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
5889         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
5890         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
5891     };
5892     static const float composite_quad[][5] = {
5893         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
5894         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
5895         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
5896         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
5897     };
5898
5899     /* Clear the render target with alpha = 0.5 */
5900     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5901     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5902
5903     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
5904     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
5905
5906     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5907     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
5908     if(!backbuffer) {
5909         goto out;
5910     }
5911
5912     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
5913     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
5914     if(!offscreen) {
5915         goto out;
5916     }
5917
5918     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
5919     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5920
5921     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5922     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5923     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5924     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5925     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
5926     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
5927     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
5928     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
5929     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5930     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5931
5932     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
5933     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5934     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
5935
5936         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
5937          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
5938          * the input alpha
5939          *
5940          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
5941          * They give essentially ZERO and ONE blend factors
5942          */
5943         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5944         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5945         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5946         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5948         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5949
5950         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5951         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5952         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5953         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5954         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5955         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5956
5957         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
5958          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
5959          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
5960          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
5961          * vertices
5962          */
5963         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
5964         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5965         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5966         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5967
5968         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5969         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5970         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5971         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5972         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5973         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5974
5975         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5976         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5977         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5978         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5980         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5981
5982         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
5983         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5984
5985         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
5986          * Disable alpha blending for the final composition
5987          */
5988         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
5989         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5990         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5991         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5992
5993         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
5994         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5995         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
5996         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5997         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5998         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5999
6000         hr = IDirect3DDevice9_EndScene(device);
6001         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6002     }
6003
6004     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6005
6006     color = getPixelColor(device, 160, 360);
6007     red =   (color & 0x00ff0000) >> 16;
6008     green = (color & 0x0000ff00) >>  8;
6009     blue =  (color & 0x000000ff);
6010     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6011        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6012
6013     color = getPixelColor(device, 160, 120);
6014     red =   (color & 0x00ff0000) >> 16;
6015     green = (color & 0x0000ff00) >>  8;
6016     blue =  (color & 0x000000ff);
6017     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6018        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6019
6020     color = getPixelColor(device, 480, 360);
6021     red =   (color & 0x00ff0000) >> 16;
6022     green = (color & 0x0000ff00) >>  8;
6023     blue =  (color & 0x000000ff);
6024     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6025        "SRCALPHA on texture returned color %08x, expected bar\n", color);
6026
6027     color = getPixelColor(device, 480, 120);
6028     red =   (color & 0x00ff0000) >> 16;
6029     green = (color & 0x0000ff00) >>  8;
6030     blue =  (color & 0x000000ff);
6031     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6032        "DSTALPHA on texture returned color %08x, expected foo\n", color);
6033
6034     out:
6035     /* restore things */
6036     if(backbuffer) {
6037         IDirect3DSurface9_Release(backbuffer);
6038     }
6039     if(offscreenTexture) {
6040         IDirect3DTexture9_Release(offscreenTexture);
6041     }
6042     if(offscreen) {
6043         IDirect3DSurface9_Release(offscreen);
6044     }
6045 }
6046
6047 struct vertex_shortcolor {
6048     float x, y, z;
6049     unsigned short r, g, b, a;
6050 };
6051 struct vertex_floatcolor {
6052     float x, y, z;
6053     float r, g, b, a;
6054 };
6055
6056 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6057 {
6058     HRESULT hr;
6059     BOOL s_ok, ub_ok, f_ok;
6060     DWORD color, size, i;
6061     void *data;
6062     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6063         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6064         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6065         D3DDECL_END()
6066     };
6067     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6068         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6069         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6070         D3DDECL_END()
6071     };
6072     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6073         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6074         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6075         D3DDECL_END()
6076     };
6077     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6078         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6079         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6080         D3DDECL_END()
6081     };
6082     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6083         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6084         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6085         D3DDECL_END()
6086     };
6087     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6088         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6089         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6090         D3DDECL_END()
6091     };
6092     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6093         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6094         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6095         D3DDECL_END()
6096     };
6097     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6098     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6099     IDirect3DVertexBuffer9 *vb, *vb2;
6100     struct vertex quad1[] =                             /* D3DCOLOR */
6101     {
6102         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6103         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6104         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6105         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6106     };
6107     struct vertex quad2[] =                             /* UBYTE4N */
6108     {
6109         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6110         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6111         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6112         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6113     };
6114     struct vertex_shortcolor quad3[] =                  /* short */
6115     {
6116         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6117         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6118         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6119         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6120     };
6121     struct vertex_floatcolor quad4[] =
6122     {
6123         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6124         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6125         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6126         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6127     };
6128     DWORD colors[] = {
6129         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6130         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6131         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6132         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6133         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6134         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6135         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6136         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6137         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6138         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6139         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6140         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6141         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6142         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6143         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6144         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6145     };
6146     float quads[] = {
6147         -1.0,   -1.0,     0.1,
6148         -1.0,    0.0,     0.1,
6149          0.0,   -1.0,     0.1,
6150          0.0,    0.0,     0.1,
6151
6152          0.0,   -1.0,     0.1,
6153          0.0,    0.0,     0.1,
6154          1.0,   -1.0,     0.1,
6155          1.0,    0.0,     0.1,
6156
6157          0.0,    0.0,     0.1,
6158          0.0,    1.0,     0.1,
6159          1.0,    0.0,     0.1,
6160          1.0,    1.0,     0.1,
6161
6162         -1.0,    0.0,     0.1,
6163         -1.0,    1.0,     0.1,
6164          0.0,    0.0,     0.1,
6165          0.0,    1.0,     0.1
6166     };
6167     struct tvertex quad_transformed[] = {
6168        {  90,    110,     0.1,      2.0,        0x00ffff00},
6169        { 570,    110,     0.1,      2.0,        0x00ffff00},
6170        {  90,    300,     0.1,      2.0,        0x00ffff00},
6171        { 570,    300,     0.1,      2.0,        0x00ffff00}
6172     };
6173     D3DCAPS9 caps;
6174
6175     memset(&caps, 0, sizeof(caps));
6176     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6177     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6178
6179     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6180     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6181
6182     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6183     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6184     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6185     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6186     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6187     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6188     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6189         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6190         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6191         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6192         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6193     } else {
6194         trace("D3DDTCAPS_UBYTE4N not supported\n");
6195         dcl_ubyte_2 = NULL;
6196         dcl_ubyte = NULL;
6197     }
6198     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6199     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6200     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6201     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6202
6203     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6204     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6205                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6206     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6207
6208     hr = IDirect3DDevice9_BeginScene(device);
6209     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6210     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6211     if(SUCCEEDED(hr)) {
6212         if(dcl_color) {
6213             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6214             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6215             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6216             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6217         }
6218
6219         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6220          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6221          * using software vertex processing. Doh!
6222          */
6223         if(dcl_ubyte) {
6224             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6225             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6226             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6227             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6228             ub_ok = SUCCEEDED(hr);
6229         }
6230
6231         if(dcl_short) {
6232             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6233             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6234             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6235             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6236             s_ok = SUCCEEDED(hr);
6237         }
6238
6239         if(dcl_float) {
6240             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6241             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6242             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6243             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6244             f_ok = SUCCEEDED(hr);
6245         }
6246
6247         hr = IDirect3DDevice9_EndScene(device);
6248         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6249     }
6250
6251     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6252     if(dcl_short) {
6253         color = getPixelColor(device, 480, 360);
6254         ok(color == 0x000000ff || !s_ok,
6255            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6256     }
6257     if(dcl_ubyte) {
6258         color = getPixelColor(device, 160, 120);
6259         ok(color == 0x0000ffff || !ub_ok,
6260            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6261     }
6262     if(dcl_color) {
6263         color = getPixelColor(device, 160, 360);
6264         ok(color == 0x00ffff00,
6265            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6266     }
6267     if(dcl_float) {
6268         color = getPixelColor(device, 480, 120);
6269         ok(color == 0x00ff0000 || !f_ok,
6270            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
6271     }
6272
6273     /* The following test with vertex buffers doesn't serve to find out new information from windows.
6274      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
6275      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
6276      * whether the immediate mode code works
6277      */
6278     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6279     hr = IDirect3DDevice9_BeginScene(device);
6280     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6281     if(SUCCEEDED(hr)) {
6282         if(dcl_color) {
6283             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
6284             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6285             memcpy(data, quad1, sizeof(quad1));
6286             hr = IDirect3DVertexBuffer9_Unlock(vb);
6287             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6288             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6289             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6290             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
6291             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6292             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6293             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6294         }
6295
6296         if(dcl_ubyte) {
6297             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
6298             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6299             memcpy(data, quad2, sizeof(quad2));
6300             hr = IDirect3DVertexBuffer9_Unlock(vb);
6301             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6302             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6303             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6304             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
6305             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6306             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6307             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6308                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6309             ub_ok = SUCCEEDED(hr);
6310         }
6311
6312         if(dcl_short) {
6313             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
6314             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6315             memcpy(data, quad3, sizeof(quad3));
6316             hr = IDirect3DVertexBuffer9_Unlock(vb);
6317             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6318             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6319             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6320             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
6321             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6322             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6323             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6324                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6325             s_ok = SUCCEEDED(hr);
6326         }
6327
6328         if(dcl_float) {
6329             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
6330             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6331             memcpy(data, quad4, sizeof(quad4));
6332             hr = IDirect3DVertexBuffer9_Unlock(vb);
6333             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6334             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6335             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6336             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
6337             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6338             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6339             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6340                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6341             f_ok = SUCCEEDED(hr);
6342         }
6343
6344         hr = IDirect3DDevice9_EndScene(device);
6345         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6346     }
6347
6348     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6349     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6350     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6351     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6352
6353     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6354     if(dcl_short) {
6355         color = getPixelColor(device, 480, 360);
6356         ok(color == 0x000000ff || !s_ok,
6357            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6358     }
6359     if(dcl_ubyte) {
6360         color = getPixelColor(device, 160, 120);
6361         ok(color == 0x0000ffff || !ub_ok,
6362            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6363     }
6364     if(dcl_color) {
6365         color = getPixelColor(device, 160, 360);
6366         ok(color == 0x00ffff00,
6367            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6368     }
6369     if(dcl_float) {
6370         color = getPixelColor(device, 480, 120);
6371         ok(color == 0x00ff0000 || !f_ok,
6372            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
6373     }
6374
6375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
6377
6378     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
6379     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6380     memcpy(data, quad_transformed, sizeof(quad_transformed));
6381     hr = IDirect3DVertexBuffer9_Unlock(vb);
6382     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6383
6384     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
6385     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6386
6387     hr = IDirect3DDevice9_BeginScene(device);
6388     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6389     if(SUCCEEDED(hr)) {
6390         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
6391         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6392         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6393         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6394
6395         hr = IDirect3DDevice9_EndScene(device);
6396         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6397     }
6398
6399     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6400     color = getPixelColor(device, 88, 108);
6401     ok(color == 0x000000ff,
6402        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
6403     color = getPixelColor(device, 92, 108);
6404     ok(color == 0x000000ff,
6405        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
6406     color = getPixelColor(device, 88, 112);
6407     ok(color == 0x000000ff,
6408        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
6409     color = getPixelColor(device, 92, 112);
6410     ok(color == 0x00ffff00,
6411        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
6412
6413     color = getPixelColor(device, 568, 108);
6414     ok(color == 0x000000ff,
6415        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
6416     color = getPixelColor(device, 572, 108);
6417     ok(color == 0x000000ff,
6418        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
6419     color = getPixelColor(device, 568, 112);
6420     ok(color == 0x00ffff00,
6421        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
6422     color = getPixelColor(device, 572, 112);
6423     ok(color == 0x000000ff,
6424        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
6425
6426     color = getPixelColor(device, 88, 298);
6427     ok(color == 0x000000ff,
6428        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
6429     color = getPixelColor(device, 92, 298);
6430     ok(color == 0x00ffff00,
6431        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
6432     color = getPixelColor(device, 88, 302);
6433     ok(color == 0x000000ff,
6434        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
6435     color = getPixelColor(device, 92, 302);
6436     ok(color == 0x000000ff,
6437        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
6438
6439     color = getPixelColor(device, 568, 298);
6440     ok(color == 0x00ffff00,
6441        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
6442     color = getPixelColor(device, 572, 298);
6443     ok(color == 0x000000ff,
6444        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
6445     color = getPixelColor(device, 568, 302);
6446     ok(color == 0x000000ff,
6447        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
6448     color = getPixelColor(device, 572, 302);
6449     ok(color == 0x000000ff,
6450        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
6451
6452     /* This test is pointless without those two declarations: */
6453     if((!dcl_color_2) || (!dcl_ubyte_2)) {
6454         skip("color-ubyte switching test declarations aren't supported\n");
6455         goto out;
6456     }
6457
6458     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
6459     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6460     memcpy(data, quads, sizeof(quads));
6461     hr = IDirect3DVertexBuffer9_Unlock(vb);
6462     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6463     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
6464                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
6465     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6466     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
6467     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6468     memcpy(data, colors, sizeof(colors));
6469     hr = IDirect3DVertexBuffer9_Unlock(vb2);
6470     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6471
6472     for(i = 0; i < 2; i++) {
6473         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6474         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
6475
6476         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
6477         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6478         if(i == 0) {
6479             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
6480         } else {
6481             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
6482         }
6483         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6484
6485         hr = IDirect3DDevice9_BeginScene(device);
6486         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6487         ub_ok = FALSE;
6488         if(SUCCEEDED(hr)) {
6489             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
6490             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6491             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6492             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6493                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6494             ub_ok = SUCCEEDED(hr);
6495
6496             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
6497             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6498             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
6499             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6500
6501             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
6502             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6503             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
6504             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6505                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6506             ub_ok = (SUCCEEDED(hr) && ub_ok);
6507
6508             hr = IDirect3DDevice9_EndScene(device);
6509             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6510         }
6511
6512         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6513         if(i == 0) {
6514             color = getPixelColor(device, 480, 360);
6515             ok(color == 0x00ff0000,
6516                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
6517             color = getPixelColor(device, 160, 120);
6518             ok(color == 0x00ffffff,
6519                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6520             color = getPixelColor(device, 160, 360);
6521             ok(color == 0x000000ff || !ub_ok,
6522                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6523             color = getPixelColor(device, 480, 120);
6524             ok(color == 0x000000ff || !ub_ok,
6525                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6526         } else {
6527             color = getPixelColor(device, 480, 360);
6528             ok(color == 0x000000ff,
6529                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
6530             color = getPixelColor(device, 160, 120);
6531             ok(color == 0x00ffffff,
6532                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6533             color = getPixelColor(device, 160, 360);
6534             ok(color == 0x00ff0000 || !ub_ok,
6535                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6536             color = getPixelColor(device, 480, 120);
6537             ok(color == 0x00ff0000 || !ub_ok,
6538                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6539         }
6540     }
6541
6542     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6543     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6544     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
6545     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6546     IDirect3DVertexBuffer9_Release(vb2);
6547
6548     out:
6549     IDirect3DVertexBuffer9_Release(vb);
6550     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
6551     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
6552     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
6553     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
6554     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
6555     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
6556     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
6557 }
6558
6559 struct vertex_float16color {
6560     float x, y, z;
6561     DWORD c1, c2;
6562 };
6563
6564 static void test_vshader_float16(IDirect3DDevice9 *device)
6565 {
6566     HRESULT hr;
6567     DWORD color;
6568     void *data;
6569     static const D3DVERTEXELEMENT9 decl_elements[] = {
6570         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6571         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6572         D3DDECL_END()
6573     };
6574     IDirect3DVertexDeclaration9 *vdecl = NULL;
6575     IDirect3DVertexBuffer9 *buffer = NULL;
6576     IDirect3DVertexShader9 *shader;
6577     DWORD shader_code[] = {
6578         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
6579         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
6580         0x90e40001, 0x0000ffff
6581     };
6582     struct vertex_float16color quad[] = {
6583         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
6584         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
6585         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
6586         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
6587
6588         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
6589         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
6590         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
6591         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
6592
6593         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
6594         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
6595         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
6596         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
6597
6598         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
6599         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
6600         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
6601         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
6602     };
6603
6604     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6605     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6606
6607     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
6608     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
6609     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
6610     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6611     IDirect3DDevice9_SetVertexShader(device, shader);
6612     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6613
6614     hr = IDirect3DDevice9_BeginScene(device);
6615     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6616     if(SUCCEEDED(hr)) {
6617         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
6618         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6619         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
6620         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6621         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
6622         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6623         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
6624         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6625         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
6626         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6627
6628         hr = IDirect3DDevice9_EndScene(device);
6629         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6630     }
6631     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6632     color = getPixelColor(device, 480, 360);
6633     ok(color == 0x00ff0000,
6634        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6635     color = getPixelColor(device, 160, 120);
6636     ok(color == 0x00000000,
6637        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6638     color = getPixelColor(device, 160, 360);
6639     ok(color == 0x0000ff00,
6640        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6641     color = getPixelColor(device, 480, 120);
6642     ok(color == 0x000000ff,
6643        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6644
6645     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6646     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6647
6648     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
6649                                              D3DPOOL_MANAGED, &buffer, NULL);
6650     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
6651     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
6652     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
6653     memcpy(data, quad, sizeof(quad));
6654     hr = IDirect3DVertexBuffer9_Unlock(buffer);
6655     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
6656     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
6657     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6658
6659     hr = IDirect3DDevice9_BeginScene(device);
6660     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6661     if(SUCCEEDED(hr)) {
6662             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
6663             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6664             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
6665             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6666             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
6667             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6668             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
6669             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6670
6671             hr = IDirect3DDevice9_EndScene(device);
6672             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6673     }
6674
6675     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6676     color = getPixelColor(device, 480, 360);
6677     ok(color == 0x00ff0000,
6678        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6679     color = getPixelColor(device, 160, 120);
6680     ok(color == 0x00000000,
6681        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6682     color = getPixelColor(device, 160, 360);
6683     ok(color == 0x0000ff00,
6684        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6685     color = getPixelColor(device, 480, 120);
6686     ok(color == 0x000000ff,
6687        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6688
6689     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6690     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6691     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6692     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6693     IDirect3DDevice9_SetVertexShader(device, NULL);
6694     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6695
6696     IDirect3DVertexDeclaration9_Release(vdecl);
6697     IDirect3DVertexShader9_Release(shader);
6698     IDirect3DVertexBuffer9_Release(buffer);
6699 }
6700
6701 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
6702 {
6703     D3DCAPS9 caps;
6704     IDirect3DTexture9 *texture;
6705     HRESULT hr;
6706     D3DLOCKED_RECT rect;
6707     unsigned int x, y;
6708     DWORD *dst, color;
6709     const float quad[] = {
6710         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
6711          1.0,   -1.0,   0.1,    1.2,   -0.2,
6712         -1.0,    1.0,   0.1,   -0.2,    1.2,
6713          1.0,    1.0,   0.1,    1.2,    1.2
6714     };
6715     memset(&caps, 0, sizeof(caps));
6716
6717     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6718     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6719     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6720         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
6721         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
6722            "Card has conditional NP2 support without power of two restriction set\n");
6723         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
6724         return;
6725     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6726         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
6727         return;
6728     }
6729
6730     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
6731     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6732
6733     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6734     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6735
6736     memset(&rect, 0, sizeof(rect));
6737     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
6738     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
6739     for(y = 0; y < 10; y++) {
6740         for(x = 0; x < 10; x++) {
6741             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
6742             if(x == 0 || x == 9 || y == 0 || y == 9) {
6743                 *dst = 0x00ff0000;
6744             } else {
6745                 *dst = 0x000000ff;
6746             }
6747         }
6748     }
6749     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6750     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
6751
6752     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6753     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6754     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
6755     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6756     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
6757     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6758     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6759     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6760
6761     hr = IDirect3DDevice9_BeginScene(device);
6762     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6763     if(SUCCEEDED(hr)) {
6764         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
6765         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6766
6767         hr = IDirect3DDevice9_EndScene(device);
6768         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6769     }
6770
6771     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6772
6773     color = getPixelColor(device,    1,  1);
6774     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
6775     color = getPixelColor(device, 639, 479);
6776     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
6777
6778     color = getPixelColor(device, 135, 101);
6779     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
6780     color = getPixelColor(device, 140, 101);
6781     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
6782     color = getPixelColor(device, 135, 105);
6783     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
6784     color = getPixelColor(device, 140, 105);
6785     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
6786
6787     color = getPixelColor(device, 135, 376);
6788     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
6789     color = getPixelColor(device, 140, 376);
6790     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
6791     color = getPixelColor(device, 135, 379);
6792     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
6793     color = getPixelColor(device, 140, 379);
6794     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
6795
6796     color = getPixelColor(device, 500, 101);
6797     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
6798     color = getPixelColor(device, 504, 101);
6799     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
6800     color = getPixelColor(device, 500, 105);
6801     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
6802     color = getPixelColor(device, 504, 105);
6803     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
6804
6805     color = getPixelColor(device, 500, 376);
6806     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
6807     color = getPixelColor(device, 504, 376);
6808     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
6809     color = getPixelColor(device, 500, 380);
6810     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
6811     color = getPixelColor(device, 504, 380);
6812     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
6813
6814     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6815     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6816     IDirect3DTexture9_Release(texture);
6817 }
6818
6819 static void vFace_register_test(IDirect3DDevice9 *device)
6820 {
6821     HRESULT hr;
6822     DWORD color;
6823     const DWORD shader_code[] = {
6824         0xffff0300,                                                             /* ps_3_0                     */
6825         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
6826         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
6827         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
6828         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
6829         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
6830         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
6831         0x0000ffff                                                              /* END                        */
6832     };
6833     IDirect3DPixelShader9 *shader;
6834     IDirect3DTexture9 *texture;
6835     IDirect3DSurface9 *surface, *backbuffer;
6836     const float quad[] = {
6837         -1.0,   -1.0,   0.1,
6838          1.0,   -1.0,   0.1,
6839         -1.0,    0.0,   0.1,
6840
6841          1.0,   -1.0,   0.1,
6842          1.0,    0.0,   0.1,
6843         -1.0,    0.0,   0.1,
6844
6845         -1.0,    0.0,   0.1,
6846         -1.0,    1.0,   0.1,
6847          1.0,    0.0,   0.1,
6848
6849          1.0,    0.0,   0.1,
6850         -1.0,    1.0,   0.1,
6851          1.0,    1.0,   0.1,
6852     };
6853     const float blit[] = {
6854          0.0,   -1.0,   0.1,    0.0,    0.0,
6855          1.0,   -1.0,   0.1,    1.0,    0.0,
6856          0.0,    1.0,   0.1,    0.0,    1.0,
6857          1.0,    1.0,   0.1,    1.0,    1.0,
6858     };
6859
6860     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6861     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
6862     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6863     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6864     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6865     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
6866     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6867     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6868     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6869     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6870     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6871     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
6872
6873     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6874     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6875
6876     hr = IDirect3DDevice9_BeginScene(device);
6877     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6878     if(SUCCEEDED(hr)) {
6879         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
6880         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6881         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6882         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6883         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6884         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6885         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6886         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6887         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6888         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6889         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6890
6891         /* Blit the texture ontp the back buffer to make it visible */
6892         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6893         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
6894         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6895         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
6896         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6897         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6898         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6899         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6900         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6901         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6902
6903         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
6904         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6905
6906         hr = IDirect3DDevice9_EndScene(device);
6907         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6908     }
6909
6910     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6911     color = getPixelColor(device, 160, 360);
6912     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6913     color = getPixelColor(device, 160, 120);
6914     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6915     color = getPixelColor(device, 480, 360);
6916     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6917     color = getPixelColor(device, 480, 120);
6918     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6919
6920     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6921     IDirect3DDevice9_SetTexture(device, 0, NULL);
6922     IDirect3DPixelShader9_Release(shader);
6923     IDirect3DSurface9_Release(surface);
6924     IDirect3DSurface9_Release(backbuffer);
6925     IDirect3DTexture9_Release(texture);
6926 }
6927
6928 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
6929 {
6930     HRESULT hr;
6931     DWORD color;
6932     int i;
6933     D3DCAPS9 caps;
6934
6935     static const float quad[][7] = {
6936         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
6937         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
6938         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
6939         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
6940     };
6941
6942     static const D3DVERTEXELEMENT9 decl_elements[] = {
6943         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6944         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6945         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6946         D3DDECL_END()
6947     };
6948
6949     /* use assymetric matrix to test loading */
6950     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
6951
6952     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
6953     IDirect3DTexture9           *texture            = NULL;
6954
6955     memset(&caps, 0, sizeof(caps));
6956     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6957     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6958     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
6959         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
6960         return;
6961     } else {
6962         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
6963          * They report that it is not supported, but after that bump mapping works properly. So just test
6964          * if the format is generally supported, and check the BUMPENVMAP flag
6965          */
6966         IDirect3D9 *d3d9;
6967
6968         IDirect3DDevice9_GetDirect3D(device, &d3d9);
6969         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
6970                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
6971         IDirect3D9_Release(d3d9);
6972         if(FAILED(hr)) {
6973             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
6974             return;
6975         }
6976     }
6977
6978     /* Generate the textures */
6979     generate_bumpmap_textures(device);
6980
6981     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
6982     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6983     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
6984     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6985     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
6986     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6987     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
6988     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6989
6990     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
6991     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6992     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
6993     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6994     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
6995     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6996
6997     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6998     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6999     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7000     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7001     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7002     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7003
7004     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7005     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7006
7007     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7008     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7009
7010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7012
7013
7014     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7015     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7016     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7017     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7018
7019     hr = IDirect3DDevice9_BeginScene(device);
7020     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7021
7022     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7023     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7024
7025     hr = IDirect3DDevice9_EndScene(device);
7026     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7027
7028     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7029     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7030
7031     color = getPixelColor(device, 320-32, 240);
7032     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7033     color = getPixelColor(device, 320+32, 240);
7034     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7035     color = getPixelColor(device, 320, 240-32);
7036     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7037     color = getPixelColor(device, 320, 240+32);
7038     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7039     color = getPixelColor(device, 320, 240);
7040     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7041     color = getPixelColor(device, 320+32, 240+32);
7042     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7043     color = getPixelColor(device, 320-32, 240+32);
7044     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7045     color = getPixelColor(device, 320+32, 240-32);
7046     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7047     color = getPixelColor(device, 320-32, 240-32);
7048     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7049
7050     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7051     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7052     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7053
7054     for(i = 0; i < 2; i++) {
7055         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7056         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7057         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7058         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7059         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7060         IDirect3DTexture9_Release(texture); /* To destroy it */
7061     }
7062
7063     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7064     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7065     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7066     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7067
7068 }
7069
7070 static void stencil_cull_test(IDirect3DDevice9 *device) {
7071     HRESULT hr;
7072     IDirect3DSurface9 *depthstencil = NULL;
7073     D3DSURFACE_DESC desc;
7074     float quad1[] = {
7075         -1.0,   -1.0,   0.1,
7076          0.0,   -1.0,   0.1,
7077         -1.0,    0.0,   0.1,
7078          0.0,    0.0,   0.1,
7079     };
7080     float quad2[] = {
7081          0.0,   -1.0,   0.1,
7082          1.0,   -1.0,   0.1,
7083          0.0,    0.0,   0.1,
7084          1.0,    0.0,   0.1,
7085     };
7086     float quad3[] = {
7087         0.0,    0.0,   0.1,
7088         1.0,    0.0,   0.1,
7089         0.0,    1.0,   0.1,
7090         1.0,    1.0,   0.1,
7091     };
7092     float quad4[] = {
7093         -1.0,    0.0,   0.1,
7094          0.0,    0.0,   0.1,
7095         -1.0,    1.0,   0.1,
7096          0.0,    1.0,   0.1,
7097     };
7098     struct vertex painter[] = {
7099        {-1.0,   -1.0,   0.0,    0x00000000},
7100        { 1.0,   -1.0,   0.0,    0x00000000},
7101        {-1.0,    1.0,   0.0,    0x00000000},
7102        { 1.0,    1.0,   0.0,    0x00000000},
7103     };
7104     WORD indices_cw[]  = {0, 1, 3};
7105     WORD indices_ccw[] = {0, 2, 3};
7106     unsigned int i;
7107     DWORD color;
7108
7109     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7110     if(depthstencil == NULL) {
7111         skip("No depth stencil buffer\n");
7112         return;
7113     }
7114     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7115     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7116     IDirect3DSurface9_Release(depthstencil);
7117     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7118         skip("No 4 or 8 bit stencil surface\n");
7119         return;
7120     }
7121
7122     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7123     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7124     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7125
7126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7132     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7133     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7134
7135     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7136     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7137     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7138     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7139     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7140     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7141
7142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7146
7147     /* First pass: Fill the stencil buffer with some values... */
7148     hr = IDirect3DDevice9_BeginScene(device);
7149     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7150     if(SUCCEEDED(hr))
7151     {
7152         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7153         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7154         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7155                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7156         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7157                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7158
7159         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7160         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7161         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7162         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7163         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7164                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7165         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7166                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7167
7168         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7169         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7170         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7171                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7172         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7173                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7174
7175         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7176         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7177         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7178                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7179         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7180                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7181
7182         hr = IDirect3DDevice9_EndScene(device);
7183         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7184     }
7185
7186     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7187     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7188     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7189     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7190     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7191     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7192     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7193     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7194     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7195     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7196     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7197     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7198     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7199
7200     /* 2nd pass: Make the stencil values visible */
7201     hr = IDirect3DDevice9_BeginScene(device);
7202     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7203     if(SUCCEEDED(hr))
7204     {
7205         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7206         for(i = 0; i < 16; i++) {
7207             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7208             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7209
7210             painter[0].diffuse = (i * 16); /* Creates shades of blue */
7211             painter[1].diffuse = (i * 16);
7212             painter[2].diffuse = (i * 16);
7213             painter[3].diffuse = (i * 16);
7214             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7215             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7216         }
7217         hr = IDirect3DDevice9_EndScene(device);
7218         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7219     }
7220
7221     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7222     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7223
7224     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7225     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7226
7227     color = getPixelColor(device, 160, 420);
7228     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7229     color = getPixelColor(device, 160, 300);
7230     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7231
7232     color = getPixelColor(device, 480, 420);
7233     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7234     color = getPixelColor(device, 480, 300);
7235     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
7236
7237     color = getPixelColor(device, 160, 180);
7238     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
7239     color = getPixelColor(device, 160, 60);
7240     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
7241
7242     color = getPixelColor(device, 480, 180);
7243     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
7244     color = getPixelColor(device, 480, 60);
7245     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7246 }
7247
7248 static void vpos_register_test(IDirect3DDevice9 *device)
7249 {
7250     HRESULT hr;
7251     DWORD color;
7252     const DWORD shader_code[] = {
7253     0xffff0300,                                                             /* ps_3_0                     */
7254     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
7255     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
7256     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
7257     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
7258     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
7259     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
7260     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
7261     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
7262     0x0000ffff                                                              /* end                        */
7263     };
7264     const DWORD shader_frac_code[] = {
7265     0xffff0300,                                                             /* ps_3_0                     */
7266     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
7267     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
7268     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
7269     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
7270     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7271     0x0000ffff                                                              /* end                        */
7272     };
7273     IDirect3DPixelShader9 *shader, *shader_frac;
7274     IDirect3DSurface9 *surface = NULL, *backbuffer;
7275     const float quad[] = {
7276         -1.0,   -1.0,   0.1,    0.0,    0.0,
7277          1.0,   -1.0,   0.1,    1.0,    0.0,
7278         -1.0,    1.0,   0.1,    0.0,    1.0,
7279          1.0,    1.0,   0.1,    1.0,    1.0,
7280     };
7281     D3DLOCKED_RECT lr;
7282     float constant[4] = {1.0, 0.0, 320, 240};
7283     DWORD *pos;
7284
7285     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7286     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7287     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7288     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7289     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
7290     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7291     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7292     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7293     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7294     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7295     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7296     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7297
7298     hr = IDirect3DDevice9_BeginScene(device);
7299     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7300     if(SUCCEEDED(hr)) {
7301         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
7302         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
7303         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7304         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7305         hr = IDirect3DDevice9_EndScene(device);
7306         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7307     }
7308
7309     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7310     /* This has to be pixel exact */
7311     color = getPixelColor(device, 319, 239);
7312     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
7313     color = getPixelColor(device, 320, 239);
7314     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
7315     color = getPixelColor(device, 319, 240);
7316     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
7317     color = getPixelColor(device, 320, 240);
7318     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
7319
7320     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
7321                                              &surface, NULL);
7322     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
7323     hr = IDirect3DDevice9_BeginScene(device);
7324     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7325     if(SUCCEEDED(hr)) {
7326         constant[2] = 16; constant[3] = 16;
7327         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
7328         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
7329         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7330         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7331         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7332         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7333         hr = IDirect3DDevice9_EndScene(device);
7334         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7335     }
7336     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
7337     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
7338
7339     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
7340     color = *pos & 0x00ffffff;
7341     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
7342     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
7343     color = *pos & 0x00ffffff;
7344     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
7345     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
7346     color = *pos & 0x00ffffff;
7347     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
7348     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
7349     color = *pos & 0x00ffffff;
7350     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
7351
7352     hr = IDirect3DSurface9_UnlockRect(surface);
7353     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
7354
7355     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
7356      * have full control over the multisampling setting inside this test
7357      */
7358     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
7359     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7360     hr = IDirect3DDevice9_BeginScene(device);
7361     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7362     if(SUCCEEDED(hr)) {
7363         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7364         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7365         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7366         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7367         hr = IDirect3DDevice9_EndScene(device);
7368         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7369     }
7370     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7371     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7372
7373     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
7374     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
7375
7376     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
7377     color = *pos & 0x00ffffff;
7378     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
7379
7380     hr = IDirect3DSurface9_UnlockRect(surface);
7381     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
7382
7383     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7384     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7385     IDirect3DPixelShader9_Release(shader);
7386     IDirect3DPixelShader9_Release(shader_frac);
7387     if(surface) IDirect3DSurface9_Release(surface);
7388     IDirect3DSurface9_Release(backbuffer);
7389 }
7390
7391 static void pointsize_test(IDirect3DDevice9 *device)
7392 {
7393     HRESULT hr;
7394     D3DCAPS9 caps;
7395     D3DMATRIX matrix;
7396     D3DMATRIX identity;
7397     float ptsize, ptsize_orig;
7398     DWORD color;
7399
7400     const float vertices[] = {
7401         64,     64,     0.1,
7402         128,    64,     0.1,
7403         192,    64,     0.1,
7404         256,    64,     0.1,
7405         320,    64,     0.1,
7406         384,    64,     0.1
7407     };
7408
7409     /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to [0.0;0.0]x[640.0;480.0]. Z is untouched */
7410     U(matrix).m[0][0] = 2.0/640.0; U(matrix).m[1][0] = 0.0;       U(matrix).m[2][0] = 0.0;   U(matrix).m[3][0] =-1.0;
7411     U(matrix).m[0][1] = 0.0;       U(matrix).m[1][1] =-2.0/480.0; U(matrix).m[2][1] = 0.0;   U(matrix).m[3][1] = 1.0;
7412     U(matrix).m[0][2] = 0.0;       U(matrix).m[1][2] = 0.0;       U(matrix).m[2][2] = 1.0;   U(matrix).m[3][2] = 0.0;
7413     U(matrix).m[0][3] = 0.0;       U(matrix).m[1][3] = 0.0;       U(matrix).m[2][3] = 0.0;   U(matrix).m[3][3] = 1.0;
7414
7415     U(identity).m[0][0] = 1.0;     U(identity).m[1][0] = 0.0;     U(identity).m[2][0] = 0.0; U(identity).m[3][0] = 0.0;
7416     U(identity).m[0][1] = 0.0;     U(identity).m[1][1] = 1.0;     U(identity).m[2][1] = 0.0; U(identity).m[3][1] = 0.0;
7417     U(identity).m[0][2] = 0.0;     U(identity).m[1][2] = 0.0;     U(identity).m[2][2] = 1.0; U(identity).m[3][2] = 0.0;
7418     U(identity).m[0][3] = 0.0;     U(identity).m[1][3] = 0.0;     U(identity).m[2][3] = 0.0; U(identity).m[3][3] = 1.0;
7419
7420     memset(&caps, 0, sizeof(caps));
7421     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7422     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7423     if(caps.MaxPointSize < 32.0) {
7424         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
7425         return;
7426     }
7427
7428     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
7429     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7430     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
7431     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
7432     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7433     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7434     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
7435     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
7436
7437     hr = IDirect3DDevice9_BeginScene(device);
7438     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7439     if(SUCCEEDED(hr)) {
7440         ptsize = 16.0;
7441         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7442         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7443         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7444         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7445
7446         ptsize = 32.0;
7447         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7448         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
7450         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7451
7452         ptsize = 31.5;
7453         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7454         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7455         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
7456         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7457
7458         if(caps.MaxPointSize >= 64.0) {
7459             ptsize = 64.0;
7460             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7461             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7462             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
7463             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7464
7465             ptsize = 63.75;
7466             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7467             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7468             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
7469             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7470         }
7471
7472         ptsize = 1.0;
7473         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7474         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7475         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
7476         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7477
7478         hr = IDirect3DDevice9_EndScene(device);
7479         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7480     }
7481     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7482     color = getPixelColor(device, 64-9, 64-9);
7483     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
7484     color = getPixelColor(device, 64-8, 64-8);
7485     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
7486     color = getPixelColor(device, 64-7, 64-7);
7487     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
7488     color = getPixelColor(device, 64+7, 64+7);
7489     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
7490     color = getPixelColor(device, 64+8, 64+8);
7491     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
7492     color = getPixelColor(device, 64+9, 64+9);
7493     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
7494
7495     color = getPixelColor(device, 128-17, 64-17);
7496     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
7497     color = getPixelColor(device, 128-16, 64-16);
7498     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
7499     color = getPixelColor(device, 128-15, 64-15);
7500     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
7501     color = getPixelColor(device, 128+15, 64+15);
7502     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
7503     color = getPixelColor(device, 128+16, 64+16);
7504     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
7505     color = getPixelColor(device, 128+17, 64+17);
7506     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
7507
7508     color = getPixelColor(device, 192-17, 64-17);
7509     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
7510     color = getPixelColor(device, 192-16, 64-16);
7511     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
7512     color = getPixelColor(device, 192-15, 64-15);
7513     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
7514     color = getPixelColor(device, 192+15, 64+15);
7515     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
7516     color = getPixelColor(device, 192+16, 64+16);
7517     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
7518     color = getPixelColor(device, 192+17, 64+17);
7519     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
7520
7521     if(caps.MaxPointSize >= 64.0) {
7522         color = getPixelColor(device, 256-33, 64-33);
7523         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
7524         color = getPixelColor(device, 256-32, 64-32);
7525         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
7526         color = getPixelColor(device, 256-31, 64-31);
7527         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
7528         color = getPixelColor(device, 256+31, 64+31);
7529         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
7530         color = getPixelColor(device, 256+32, 64+32);
7531         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
7532         color = getPixelColor(device, 256+33, 64+33);
7533         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
7534
7535         color = getPixelColor(device, 384-33, 64-33);
7536         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
7537         color = getPixelColor(device, 384-32, 64-32);
7538         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
7539         color = getPixelColor(device, 384-31, 64-31);
7540         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
7541         color = getPixelColor(device, 384+31, 64+31);
7542         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
7543         color = getPixelColor(device, 384+32, 64+32);
7544         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
7545         color = getPixelColor(device, 384+33, 64+33);
7546         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
7547     }
7548
7549     color = getPixelColor(device, 320-1, 64-1);
7550     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
7551     color = getPixelColor(device, 320-0, 64-0);
7552     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
7553     color = getPixelColor(device, 320+1, 64+1);
7554     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
7555
7556     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
7557     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
7558     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
7559     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
7560 }
7561
7562 START_TEST(visual)
7563 {
7564     IDirect3DDevice9 *device_ptr;
7565     D3DCAPS9 caps;
7566     HRESULT hr;
7567     DWORD color;
7568
7569     d3d9_handle = LoadLibraryA("d3d9.dll");
7570     if (!d3d9_handle)
7571     {
7572         skip("Could not load d3d9.dll\n");
7573         return;
7574     }
7575
7576     device_ptr = init_d3d9();
7577     if (!device_ptr)
7578     {
7579         skip("Creating the device failed\n");
7580         return;
7581     }
7582
7583     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
7584
7585     /* Check for the reliability of the returned data */
7586     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
7587     if(FAILED(hr))
7588     {
7589         trace("Clear failed, can't assure correctness of the test results, skipping\n");
7590         goto cleanup;
7591     }
7592     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
7593
7594     color = getPixelColor(device_ptr, 1, 1);
7595     if(color !=0x00ff0000)
7596     {
7597         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
7598         goto cleanup;
7599     }
7600
7601     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
7602     if(FAILED(hr))
7603     {
7604         trace("Clear failed, can't assure correctness of the test results, skipping\n");
7605         goto cleanup;
7606     }
7607     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
7608
7609     color = getPixelColor(device_ptr, 639, 479);
7610     if(color != 0x0000ddee)
7611     {
7612         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
7613         goto cleanup;
7614     }
7615
7616     /* Now execute the real tests */
7617     lighting_test(device_ptr);
7618     clear_test(device_ptr);
7619     fog_test(device_ptr);
7620     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
7621     {
7622         test_cube_wrap(device_ptr);
7623     } else {
7624         skip("No cube texture support\n");
7625     }
7626     z_range_test(device_ptr);
7627     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
7628     {
7629         maxmip_test(device_ptr);
7630     }
7631     else
7632     {
7633         skip("No mipmap support\n");
7634     }
7635     offscreen_test(device_ptr);
7636     alpha_test(device_ptr);
7637     shademode_test(device_ptr);
7638     srgbtexture_test(device_ptr);
7639     release_buffer_test(device_ptr);
7640     float_texture_test(device_ptr);
7641     g16r16_texture_test(device_ptr);
7642     texture_transform_flags_test(device_ptr);
7643     autogen_mipmap_test(device_ptr);
7644     fixed_function_decl_test(device_ptr);
7645     conditional_np2_repeat_test(device_ptr);
7646     fixed_function_bumpmap_test(device_ptr);
7647     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
7648         stencil_cull_test(device_ptr);
7649     } else {
7650         skip("No two sided stencil support\n");
7651     }
7652     pointsize_test(device_ptr);
7653
7654     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
7655     {
7656         test_constant_clamp_vs(device_ptr);
7657         test_compare_instructions(device_ptr);
7658     }
7659     else skip("No vs_1_1 support\n");
7660
7661     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
7662     {
7663         test_mova(device_ptr);
7664         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
7665             test_vshader_input(device_ptr);
7666             test_vshader_float16(device_ptr);
7667         } else {
7668             skip("No vs_3_0 support\n");
7669         }
7670     }
7671     else skip("No vs_2_0 support\n");
7672
7673     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
7674     {
7675         fog_with_shader_test(device_ptr);
7676         fog_srgbwrite_test(device_ptr);
7677     }
7678     else skip("No vs_1_1 and ps_1_1 support\n");
7679
7680     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
7681     {
7682         texbem_test(device_ptr);
7683         texdepth_test(device_ptr);
7684         texkill_test(device_ptr);
7685         x8l8v8u8_test(device_ptr);
7686         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
7687             constant_clamp_ps_test(device_ptr);
7688             cnd_test(device_ptr);
7689             if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
7690                 nested_loop_test(device_ptr);
7691                 fixed_function_varying_test(device_ptr);
7692                 vFace_register_test(device_ptr);
7693                 vpos_register_test(device_ptr);
7694                 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
7695                     vshader_version_varying_test(device_ptr);
7696                     pshader_version_varying_test(device_ptr);
7697                 } else {
7698                     skip("No vs_3_0 support\n");
7699                 }
7700             } else {
7701                 skip("No ps_3_0 support\n");
7702             }
7703         }
7704     }
7705     else skip("No ps_1_1 support\n");
7706
7707 cleanup:
7708     if(device_ptr) {
7709         ULONG ref;
7710
7711         D3DPRESENT_PARAMETERS present_parameters;
7712         IDirect3DSwapChain9 *swapchain;
7713         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
7714         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
7715         IDirect3DSwapChain9_Release(swapchain);
7716         ref = IDirect3DDevice9_Release(device_ptr);
7717         DestroyWindow(present_parameters.hDeviceWindow);
7718         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
7719     }
7720 }