quartz: Silence requests for ipin on filters.
[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;
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
2402     memset(&lr, 0, sizeof(lr));
2403     memset(&lb, 0, sizeof(lb));
2404     IDirect3DDevice9_GetDirect3D(device, &d3d);
2405     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2406                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2407         fmt = D3DFMT_A16B16G16R16;
2408     }
2409     IDirect3D9_Release(d3d);
2410
2411     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2412     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2413     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
2414     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2415     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
2416     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
2417     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2418     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
2419     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2420     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
2421     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2422     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
2423     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2424     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
2425     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2426     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
2427     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
2428     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
2429     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2430     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
2431     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2432     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2433
2434     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2435     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
2436     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
2437                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
2438     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
2439     if(!texture) {
2440         skip("Failed to create the test texture\n");
2441         return;
2442     }
2443
2444     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
2445      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
2446      * 1.0 in red and green for the x and y coords
2447      */
2448     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2449     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
2450     for(y = 0; y < caps.MaxTextureHeight; y++) {
2451         for(x = 0; x < caps.MaxTextureWidth; x++) {
2452             double r_f = (double) y / (double) caps.MaxTextureHeight;
2453             double g_f = (double) x / (double) caps.MaxTextureWidth;
2454             if(fmt == D3DFMT_A16B16G16R16) {
2455                 unsigned short r, g;
2456                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
2457                 r = (unsigned short) (r_f * 65536.0);
2458                 g = (unsigned short) (g_f * 65536.0);
2459                 dst[0] = r;
2460                 dst[1] = g;
2461                 dst[2] = 0;
2462                 dst[3] = 65535;
2463             } else {
2464                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
2465                 unsigned char r = (unsigned char) (r_f * 255.0);
2466                 unsigned char g = (unsigned char) (g_f * 255.0);
2467                 dst[0] = 0;
2468                 dst[1] = g;
2469                 dst[2] = r;
2470                 dst[3] = 255;
2471             }
2472         }
2473     }
2474     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2475     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
2476     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2477     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2478
2479     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2480     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2481     hr = IDirect3DDevice9_BeginScene(device);
2482     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2483     if(SUCCEEDED(hr))
2484     {
2485         float quad1[] = {
2486             -1.0,      -1.0,       0.1,     1.0,    1.0,
2487             -1.0,       0.0,       0.1,     1.0,    1.0,
2488              0.0,      -1.0,       0.1,     1.0,    1.0,
2489              0.0,       0.0,       0.1,     1.0,    1.0,
2490         };
2491         float quad2[] = {
2492             -1.0,       0.0,       0.1,     1.0,    1.0,
2493             -1.0,       1.0,       0.1,     1.0,    1.0,
2494              0.0,       0.0,       0.1,     1.0,    1.0,
2495              0.0,       1.0,       0.1,     1.0,    1.0,
2496         };
2497         float quad3[] = {
2498              0.0,       0.0,       0.1,     0.5,    0.5,
2499              0.0,       1.0,       0.1,     0.5,    0.5,
2500              1.0,       0.0,       0.1,     0.5,    0.5,
2501              1.0,       1.0,       0.1,     0.5,    0.5,
2502         };
2503         float quad4[] = {
2504              320,       480,       0.1,     1.0,    0.0,    1.0,
2505              320,       240,       0.1,     1.0,    0.0,    1.0,
2506              640,       480,       0.1,     1.0,    0.0,    1.0,
2507              640,       240,       0.1,     1.0,    0.0,    1.0,
2508         };
2509         float mat[16] = {0.0, 0.0, 0.0, 0.0,
2510                           0.0, 0.0, 0.0, 0.0,
2511                           0.0, 0.0, 0.0, 0.0,
2512                           0.0, 0.0, 0.0, 0.0};
2513
2514         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
2515         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2516         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2518         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2519
2520         /* What happens with transforms enabled? */
2521         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2522         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2523         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2524         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2525
2526         /* What happens if 4 coords are used, but only 2 given ?*/
2527         mat[8] = 1.0;
2528         mat[13] = 1.0;
2529         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2530         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2531         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2532         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2533         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2534         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2535
2536         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
2537          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
2538          * due to the coords in the vertices. (turns out red, indeed)
2539          */
2540         memset(mat, 0, sizeof(mat));
2541         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2542         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2543         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
2544         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2545         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2546         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2547         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2548         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2549
2550         hr = IDirect3DDevice9_EndScene(device);
2551         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2552     }
2553     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2554     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2555     color = getPixelColor(device, 160, 360);
2556     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
2557     color = getPixelColor(device, 160, 120);
2558     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2559     color = getPixelColor(device, 480, 120);
2560     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
2561     color = getPixelColor(device, 480, 360);
2562     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
2563
2564     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2565     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2566
2567     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2568     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2569     hr = IDirect3DDevice9_BeginScene(device);
2570     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2571     if(SUCCEEDED(hr))
2572     {
2573         float quad1[] = {
2574             -1.0,      -1.0,       0.1,     0.8,    0.2,
2575             -1.0,       0.0,       0.1,     0.8,    0.2,
2576              0.0,      -1.0,       0.1,     0.8,    0.2,
2577              0.0,       0.0,       0.1,     0.8,    0.2,
2578         };
2579         float quad2[] = {
2580             -1.0,       0.0,       0.1,     0.5,    1.0,
2581             -1.0,       1.0,       0.1,     0.5,    1.0,
2582              0.0,       0.0,       0.1,     0.5,    1.0,
2583              0.0,       1.0,       0.1,     0.5,    1.0,
2584         };
2585         float quad3[] = {
2586              0.0,       0.0,       0.1,     0.5,    1.0,
2587              0.0,       1.0,       0.1,     0.5,    1.0,
2588              1.0,       0.0,       0.1,     0.5,    1.0,
2589              1.0,       1.0,       0.1,     0.5,    1.0,
2590         };
2591         float quad4[] = {
2592              0.0,      -1.0,       0.1,     0.8,    0.2,
2593              0.0,       0.0,       0.1,     0.8,    0.2,
2594              1.0,      -1.0,       0.1,     0.8,    0.2,
2595              1.0,       0.0,       0.1,     0.8,    0.2,
2596         };
2597         float mat[16] = {0.0, 0.0, 0.0, 0.0,
2598                           0.0, 0.0, 0.0, 0.0,
2599                           0.0, 1.0, 0.0, 0.0,
2600                           0.0, 0.0, 0.0, 0.0};
2601
2602         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
2603          */
2604         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2605         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2606         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2607         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2608
2609         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2610         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2611
2612         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
2613          * it behaves like COUNT2 because normal textures require 2 coords
2614          */
2615         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2616         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2617         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
2618         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2619
2620         /* Just to be sure, the same as quad2 above */
2621         memset(mat, 0, sizeof(mat));
2622         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2623         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2624         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2625         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2626         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2627         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2628
2629         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
2630          * used? And what happens to the first?
2631          */
2632         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2633         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2635         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2636
2637         hr = IDirect3DDevice9_EndScene(device);
2638         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2639     }
2640     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2641     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2642     color = getPixelColor(device, 160, 360);
2643     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
2644     color = getPixelColor(device, 160, 120);
2645     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2646     color = getPixelColor(device, 480, 120);
2647     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
2648        "quad 3 has color %08x, expected 0x00ff8000\n", color);
2649     color = getPixelColor(device, 480, 360);
2650     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
2651        "quad 4 has color %08x, expected 0x0033cc00\n", color);
2652
2653     IDirect3DTexture9_Release(texture);
2654
2655     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
2656     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2657     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
2658      * Thus watch out if sampling from texels between 0 and 1.
2659      */
2660     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
2661     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
2662        "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
2663     if(!volume) {
2664         skip("Failed to create a volume texture\n");
2665         goto out;
2666     }
2667
2668     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
2669     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
2670     for(z = 0; z < 32; z++) {
2671         for(y = 0; y < 32; y++) {
2672             for(x = 0; x < 32; x++) {
2673                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
2674                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
2675                 float r_f = (float) x / 31.0;
2676                 float g_f = (float) y / 31.0;
2677                 float b_f = (float) z / 31.0;
2678
2679                 if(fmt == D3DFMT_A16B16G16R16) {
2680                     unsigned short *mem_s = mem;
2681                     mem_s[0]  = r_f * 65535.0;
2682                     mem_s[1]  = g_f * 65535.0;
2683                     mem_s[2]  = b_f * 65535.0;
2684                     mem_s[3]  = 65535;
2685                 } else {
2686                     unsigned char *mem_c = mem;
2687                     mem_c[0]  = b_f * 255.0;
2688                     mem_c[1]  = g_f * 255.0;
2689                     mem_c[2]  = r_f * 255.0;
2690                     mem_c[3]  = 255;
2691                 }
2692             }
2693         }
2694     }
2695     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
2696     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2697
2698     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
2699     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2700
2701     hr = IDirect3DDevice9_BeginScene(device);
2702     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2703     if(SUCCEEDED(hr))
2704     {
2705         float quad1[] = {
2706             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2707             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2708              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2709              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
2710         };
2711         float quad2[] = {
2712             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2713             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
2714              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2715              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
2716         };
2717         float quad3[] = {
2718              0.0,       0.0,       0.1,     0.0,    0.0,
2719              0.0,       1.0,       0.1,     0.0,    0.0,
2720              1.0,       0.0,       0.1,     0.0,    0.0,
2721              1.0,       1.0,       0.1,     0.0,    0.0
2722         };
2723         float quad4[] = {
2724              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2725              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2726              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2727              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
2728         };
2729         float mat[16] = {1.0, 0.0, 0.0, 0.0,
2730                          0.0, 0.0, 1.0, 0.0,
2731                          0.0, 1.0, 0.0, 0.0,
2732                          0.0, 0.0, 0.0, 1.0};
2733         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2734         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2735
2736         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
2737          * values
2738          */
2739         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2740         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2741         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2742         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2744         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2745
2746         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
2747          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
2748          * otherwise the w will be missing(blue).
2749          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
2750          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
2751          */
2752         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2753         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2754         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2755         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2756
2757         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
2758         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2759         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2760         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2761         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2762         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2763         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2764         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2765         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2766
2767         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
2768          * disable. ATI extends it up to the amount of values needed for the volume texture
2769          */
2770         memset(mat, 0, sizeof(mat));
2771         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2772         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2773         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2774         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2775         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2776         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2778         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2779
2780         hr = IDirect3DDevice9_EndScene(device);
2781         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2782     }
2783     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2784     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2785
2786     color = getPixelColor(device, 160, 360);
2787     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
2788     color = getPixelColor(device, 160, 120);
2789     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
2790        "quad 2 has color %08x, expected 0x00ffff00\n", color);
2791     color = getPixelColor(device, 480, 120);
2792     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
2793     color = getPixelColor(device, 480, 360);
2794     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
2795
2796     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
2797     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2798     hr = IDirect3DDevice9_BeginScene(device);
2799     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2800     if(SUCCEEDED(hr))
2801     {
2802         float quad1[] = {
2803             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2804             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
2805              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
2806              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
2807         };
2808         float quad2[] = {
2809             -1.0,       0.0,       0.1,
2810             -1.0,       1.0,       0.1,
2811              0.0,       0.0,       0.1,
2812              0.0,       1.0,       0.1,
2813         };
2814         float quad3[] = {
2815              0.0,       0.0,       0.1,     1.0,
2816              0.0,       1.0,       0.1,     1.0,
2817              1.0,       0.0,       0.1,     1.0,
2818              1.0,       1.0,       0.1,     1.0
2819         };
2820         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
2821                            0.0, 0.0, 0.0, 0.0,
2822                            0.0, 0.0, 0.0, 0.0,
2823                            0.0, 1.0, 0.0, 0.0};
2824         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
2825                            1.0, 0.0, 0.0, 0.0,
2826                            0.0, 1.0, 0.0, 0.0,
2827                            0.0, 0.0, 1.0, 0.0};
2828         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2829         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2830
2831         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
2832          */
2833         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2834         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2835         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2836         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2837         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2838         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2839
2840         /* None passed */
2841         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2842         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2843         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2844         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
2846         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2847
2848         /* 4 used, 1 passed */
2849         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
2850         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2851         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
2852         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2853         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
2854         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2855
2856         hr = IDirect3DDevice9_EndScene(device);
2857         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2858     }
2859     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2860     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2861     color = getPixelColor(device, 160, 360);
2862     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
2863     color = getPixelColor(device, 160, 120);
2864     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
2865     color = getPixelColor(device, 480, 120);
2866     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
2867     /* Quad4: unused */
2868
2869     IDirect3DVolumeTexture9_Release(volume);
2870
2871     out:
2872     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2873     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2874     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2875     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2876     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
2877     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2878     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2879     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2880     IDirect3DVertexDeclaration9_Release(decl);
2881     IDirect3DVertexDeclaration9_Release(decl2);
2882 }
2883
2884 static void texdepth_test(IDirect3DDevice9 *device)
2885 {
2886     IDirect3DPixelShader9 *shader;
2887     HRESULT hr;
2888     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
2889     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
2890     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
2891     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
2892     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
2893     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
2894     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
2895     DWORD shader_code[] = {
2896         0xffff0104,                                                                 /* ps_1_4               */
2897         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
2898         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
2899         0x0000fffd,                                                                 /* phase                */
2900         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
2901         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
2902         0x0000ffff                                                                  /* end                  */
2903     };
2904     DWORD color;
2905     float vertex[] = {
2906        -1.0,   -1.0,    0.0,
2907         1.0,   -1.0,    1.0,
2908        -1.0,    1.0,    0.0,
2909         1.0,    1.0,    1.0
2910     };
2911
2912     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
2913     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2914
2915     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
2916     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2917     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2918     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2919     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2920     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2921     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2922     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2923     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2924
2925     /* Fill the depth buffer with a gradient */
2926     hr = IDirect3DDevice9_BeginScene(device);
2927     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2928     if(SUCCEEDED(hr))
2929     {
2930         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2931         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2932         hr = IDirect3DDevice9_EndScene(device);
2933         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2934     }
2935
2936     /* Now perform the actual tests. Same geometry, but with the shader */
2937     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2938     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2939     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2940     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2941     hr = IDirect3DDevice9_SetPixelShader(device, shader);
2942     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2943
2944     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
2945     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2946     hr = IDirect3DDevice9_BeginScene(device);
2947     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2948     if(SUCCEEDED(hr))
2949     {
2950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2951         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2952
2953         hr = IDirect3DDevice9_EndScene(device);
2954         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2955     }
2956
2957     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2958     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2959     color = getPixelColor(device, 158, 240);
2960     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2961     color = getPixelColor(device, 162, 240);
2962     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
2963
2964     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2965
2966     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
2967     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2968     hr = IDirect3DDevice9_BeginScene(device);
2969     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2970     if(SUCCEEDED(hr))
2971     {
2972         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2973         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2974
2975         hr = IDirect3DDevice9_EndScene(device);
2976         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2977     }
2978
2979     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2980     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2981     color = getPixelColor(device, 318, 240);
2982     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2983     color = getPixelColor(device, 322, 240);
2984     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
2985
2986     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2987
2988     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
2989     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2990     hr = IDirect3DDevice9_BeginScene(device);
2991     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2992     if(SUCCEEDED(hr))
2993     {
2994         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2995         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2996
2997         hr = IDirect3DDevice9_EndScene(device);
2998         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2999     }
3000     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3001     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3002
3003     color = getPixelColor(device, 1, 240);
3004     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3005
3006     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3007
3008     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3010     hr = IDirect3DDevice9_BeginScene(device);
3011     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3012     if(SUCCEEDED(hr))
3013     {
3014         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3015         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3016
3017         hr = IDirect3DDevice9_EndScene(device);
3018         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3019     }
3020     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3021     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3022     color = getPixelColor(device, 318, 240);
3023     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3024     color = getPixelColor(device, 322, 240);
3025     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3026
3027     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3028
3029     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3030     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3031     hr = IDirect3DDevice9_BeginScene(device);
3032     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3033     if(SUCCEEDED(hr))
3034     {
3035         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3036         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3037
3038         hr = IDirect3DDevice9_EndScene(device);
3039         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3040     }
3041     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3042     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3043
3044     color = getPixelColor(device, 1, 240);
3045     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3046
3047     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3048
3049     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3050     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3051     hr = IDirect3DDevice9_BeginScene(device);
3052     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3053     if(SUCCEEDED(hr))
3054     {
3055         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3056         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3057
3058         hr = IDirect3DDevice9_EndScene(device);
3059         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3060     }
3061     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3062     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3063
3064     color = getPixelColor(device, 638, 240);
3065     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3066
3067     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3068
3069     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3070     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3071     hr = IDirect3DDevice9_BeginScene(device);
3072     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3073     if(SUCCEEDED(hr))
3074     {
3075         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3076         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3077
3078         hr = IDirect3DDevice9_EndScene(device);
3079         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3080     }
3081     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3082     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3083
3084     color = getPixelColor(device, 638, 240);
3085     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3086
3087     /* Cleanup */
3088     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3089     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3090     IDirect3DPixelShader9_Release(shader);
3091
3092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3093     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3094     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3095     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3096 }
3097
3098 static void texkill_test(IDirect3DDevice9 *device)
3099 {
3100     IDirect3DPixelShader9 *shader;
3101     HRESULT hr;
3102     DWORD color;
3103
3104     const float vertex[] = {
3105     /*                          bottom  top    right    left */
3106         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3107          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3108         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3109          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3110     };
3111
3112     DWORD shader_code_11[] = {
3113     0xffff0101,                                                             /* ps_1_1                     */
3114     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3115     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3116     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3117     0x0000ffff                                                              /* end                        */
3118     };
3119     DWORD shader_code_20[] = {
3120     0xffff0200,                                                             /* ps_2_0                     */
3121     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3122     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3123     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3124     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3125     0x0000ffff                                                              /* end                        */
3126     };
3127
3128     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3129     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3130     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3131     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3132
3133     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3134     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3135     hr = IDirect3DDevice9_BeginScene(device);
3136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3137     if(SUCCEEDED(hr))
3138     {
3139         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3140         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3142         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3143         hr = IDirect3DDevice9_EndScene(device);
3144         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3145     }
3146     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3147     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3148     color = getPixelColor(device, 63, 46);
3149     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3150     color = getPixelColor(device, 66, 46);
3151     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3152     color = getPixelColor(device, 63, 49);
3153     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3154     color = getPixelColor(device, 66, 49);
3155     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3156
3157     color = getPixelColor(device, 578, 46);
3158     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3159     color = getPixelColor(device, 575, 46);
3160     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3161     color = getPixelColor(device, 578, 49);
3162     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3163     color = getPixelColor(device, 575, 49);
3164     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3165
3166     color = getPixelColor(device, 63, 430);
3167     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3168     color = getPixelColor(device, 63, 433);
3169     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3170     color = getPixelColor(device, 66, 433);
3171     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3172     color = getPixelColor(device, 66, 430);
3173     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3174
3175     color = getPixelColor(device, 578, 430);
3176     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3177     color = getPixelColor(device, 578, 433);
3178     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3179     color = getPixelColor(device, 575, 433);
3180     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3181     color = getPixelColor(device, 575, 430);
3182     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3183
3184     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3185     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3186     IDirect3DPixelShader9_Release(shader);
3187
3188     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3190     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3191     if(FAILED(hr)) {
3192         skip("Failed to create 2.0 test shader, most likely not supported\n");
3193         return;
3194     }
3195
3196     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3197     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3198     hr = IDirect3DDevice9_BeginScene(device);
3199     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3200     if(SUCCEEDED(hr))
3201     {
3202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3203         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3204         hr = IDirect3DDevice9_EndScene(device);
3205         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3206     }
3207     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3208
3209     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3210     color = getPixelColor(device, 63, 46);
3211     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3212     color = getPixelColor(device, 66, 46);
3213     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3214     color = getPixelColor(device, 63, 49);
3215     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3216     color = getPixelColor(device, 66, 49);
3217     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3218
3219     color = getPixelColor(device, 578, 46);
3220     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3221     color = getPixelColor(device, 575, 46);
3222     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3223     color = getPixelColor(device, 578, 49);
3224     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3225     color = getPixelColor(device, 575, 49);
3226     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3227
3228     color = getPixelColor(device, 63, 430);
3229     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3230     color = getPixelColor(device, 63, 433);
3231     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3232     color = getPixelColor(device, 66, 433);
3233     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3234     color = getPixelColor(device, 66, 430);
3235     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3236
3237     color = getPixelColor(device, 578, 430);
3238     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3239     color = getPixelColor(device, 578, 433);
3240     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3241     color = getPixelColor(device, 575, 433);
3242     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3243     color = getPixelColor(device, 575, 430);
3244     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3245
3246     /* Cleanup */
3247     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3248     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3249     IDirect3DPixelShader9_Release(shader);
3250 }
3251
3252 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3253 {
3254     IDirect3D9 *d3d9;
3255     HRESULT hr;
3256     IDirect3DTexture9 *texture;
3257     IDirect3DPixelShader9 *shader;
3258     IDirect3DPixelShader9 *shader2;
3259     D3DLOCKED_RECT lr;
3260     DWORD color;
3261     DWORD shader_code[] = {
3262         0xffff0101,                             /* ps_1_1       */
3263         0x00000042, 0xb00f0000,                 /* tex t0       */
3264         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3265         0x0000ffff                              /* end          */
3266     };
3267     DWORD shader_code2[] = {
3268         0xffff0101,                             /* ps_1_1       */
3269         0x00000042, 0xb00f0000,                 /* tex t0       */
3270         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3271         0x0000ffff                              /* end          */
3272     };
3273
3274     float quad[] = {
3275        -1.0,   -1.0,   0.1,     0.5,    0.5,
3276         1.0,   -1.0,   0.1,     0.5,    0.5,
3277        -1.0,    1.0,   0.1,     0.5,    0.5,
3278         1.0,    1.0,   0.1,     0.5,    0.5,
3279     };
3280
3281     memset(&lr, 0, sizeof(lr));
3282     IDirect3DDevice9_GetDirect3D(device, &d3d9);
3283     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3284                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
3285     IDirect3D9_Release(d3d9);
3286     if(FAILED(hr)) {
3287         skip("No D3DFMT_X8L8V8U8 support\n");
3288     };
3289
3290     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3291     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3292
3293     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
3294     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
3295     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3296     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
3297     *((DWORD *) lr.pBits) = 0x11ca3141;
3298     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3299     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
3300
3301     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3302     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3303     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
3304     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3305
3306     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3307     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
3308     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3309     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3310     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3311     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3312
3313     hr = IDirect3DDevice9_BeginScene(device);
3314     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3315     if(SUCCEEDED(hr))
3316     {
3317         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3318         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3319
3320         hr = IDirect3DDevice9_EndScene(device);
3321         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3322     }
3323     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3324     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3325     color = getPixelColor(device, 578, 430);
3326     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
3327        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
3328
3329     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
3330     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3331     hr = IDirect3DDevice9_BeginScene(device);
3332     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3333     if(SUCCEEDED(hr))
3334     {
3335         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3336         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3337
3338         hr = IDirect3DDevice9_EndScene(device);
3339         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3340     }
3341     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3342     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3343     color = getPixelColor(device, 578, 430);
3344     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
3345
3346     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3347     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3348     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3349     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3350     IDirect3DPixelShader9_Release(shader);
3351     IDirect3DPixelShader9_Release(shader2);
3352     IDirect3DTexture9_Release(texture);
3353 }
3354
3355 static void autogen_mipmap_test(IDirect3DDevice9 *device)
3356 {
3357     HRESULT hr;
3358     IDirect3D9 *d3d;
3359     IDirect3DTexture9 *texture = NULL;
3360     IDirect3DSurface9 *surface;
3361     DWORD color;
3362     const RECT r1 = {256, 256, 512, 512};
3363     const RECT r2 = {512, 256, 768, 512};
3364     const RECT r3 = {256, 512, 512, 768};
3365     const RECT r4 = {512, 512, 768, 768};
3366     unsigned int x, y;
3367     D3DLOCKED_RECT lr;
3368     memset(&lr, 0, sizeof(lr));
3369
3370     IDirect3DDevice9_GetDirect3D(device, &d3d);
3371     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3372        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
3373         skip("No autogenmipmap support\n");
3374         IDirect3D9_Release(d3d);
3375         return;
3376     }
3377     IDirect3D9_Release(d3d);
3378
3379     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3380     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3381
3382     /* Make the mipmap big, so that a smaller mipmap is used
3383      */
3384     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
3385                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
3386     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3387
3388     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3389     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
3390     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
3391     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
3392     for(y = 0; y < 1024; y++) {
3393         for(x = 0; x < 1024; x++) {
3394             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
3395             POINT pt;
3396
3397             pt.x = x;
3398             pt.y = y;
3399             if(PtInRect(&r1, pt)) {
3400                 *dst = 0xffff0000;
3401             } else if(PtInRect(&r2, pt)) {
3402                 *dst = 0xff00ff00;
3403             } else if(PtInRect(&r3, pt)) {
3404                 *dst = 0xff0000ff;
3405             } else if(PtInRect(&r4, pt)) {
3406                 *dst = 0xff000000;
3407             } else {
3408                 *dst = 0xffffffff;
3409             }
3410         }
3411     }
3412     hr = IDirect3DSurface9_UnlockRect(surface);
3413     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3414     IDirect3DSurface9_Release(surface);
3415
3416     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3417     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3418     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3419     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3420
3421     hr = IDirect3DDevice9_BeginScene(device);
3422     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3423     if(SUCCEEDED(hr)) {
3424         const float quad[] =  {
3425            -0.5,   -0.5,    0.1,    0.0,    0.0,
3426            -0.5,    0.5,    0.1,    0.0,    1.0,
3427             0.5,   -0.5,    0.1,    1.0,    0.0,
3428             0.5,    0.5,    0.1,    1.0,    1.0
3429         };
3430
3431         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3432         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3433         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3434         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3435         hr = IDirect3DDevice9_EndScene(device);
3436         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3437     }
3438     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3439     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3440     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3441     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3442     IDirect3DTexture9_Release(texture);
3443
3444     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3445     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3446     color = getPixelColor(device, 200, 200);
3447     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
3448     color = getPixelColor(device, 280, 200);
3449     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
3450     color = getPixelColor(device, 360, 200);
3451     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
3452     color = getPixelColor(device, 440, 200);
3453     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3454     color = getPixelColor(device, 200, 270);
3455     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
3456     color = getPixelColor(device, 280, 270);
3457     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
3458     color = getPixelColor(device, 360, 270);
3459     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
3460     color = getPixelColor(device, 440, 270);
3461     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3462 }
3463
3464 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
3465 {
3466     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
3467     IDirect3DVertexDeclaration9 *decl;
3468     HRESULT hr;
3469     DWORD color;
3470     DWORD shader_code_11[] =  {
3471         0xfffe0101,                                         /* vs_1_1           */
3472         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3473         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3474         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3475         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3476         0x0000ffff                                          /* end              */
3477     };
3478     DWORD shader_code_11_2[] =  {
3479         0xfffe0101,                                         /* vs_1_1           */
3480         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
3481         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
3482         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3483         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3484         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3485         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3486         0x0000ffff                                          /* end              */
3487     };
3488     DWORD shader_code_20[] =  {
3489         0xfffe0200,                                         /* vs_2_0           */
3490         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3491         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3492         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3493         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3494         0x0000ffff                                          /* end              */
3495     };
3496     DWORD shader_code_20_2[] =  {
3497         0xfffe0200,                                         /* vs_2_0           */
3498         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
3499         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
3500         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
3501         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3502         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
3503         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
3504         0x0000ffff                                          /* end              */
3505     };
3506     static const D3DVERTEXELEMENT9 decl_elements[] = {
3507         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3508         D3DDECL_END()
3509     };
3510     float quad1[] = {
3511         -1.0,   -1.0,   0.1,
3512          0.0,   -1.0,   0.1,
3513         -1.0,    0.0,   0.1,
3514          0.0,    0.0,   0.1
3515     };
3516     float quad2[] = {
3517          0.0,   -1.0,   0.1,
3518          1.0,   -1.0,   0.1,
3519          0.0,    0.0,   0.1,
3520          1.0,    0.0,   0.1
3521     };
3522     float quad3[] = {
3523          0.0,    0.0,   0.1,
3524          1.0,    0.0,   0.1,
3525          0.0,    1.0,   0.1,
3526          1.0,    1.0,   0.1
3527     };
3528     float quad4[] = {
3529         -1.0,    0.0,   0.1,
3530          0.0,    0.0,   0.1,
3531         -1.0,    1.0,   0.1,
3532          0.0,    1.0,   0.1
3533     };
3534     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3535     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3536
3537     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3538     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3539
3540     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
3541     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3542     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
3543     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3544     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
3545     if(FAILED(hr)) shader_20 = NULL;
3546     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
3547     if(FAILED(hr)) shader_20_2 = NULL;
3548     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3549     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3550
3551     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
3552     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3553     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
3554     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3555     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3556     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3557
3558     hr = IDirect3DDevice9_BeginScene(device);
3559     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3560     if(SUCCEEDED(hr))
3561     {
3562         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
3563         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3564         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3565         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3566
3567         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
3568         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3569         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3570         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3571
3572         if(shader_20) {
3573             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
3574             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3575             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3576             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3577         }
3578
3579         if(shader_20_2) {
3580             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
3581             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3582             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3583             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3584         }
3585
3586         hr = IDirect3DDevice9_EndScene(device);
3587         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3588     }
3589     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3590     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3591
3592     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3593     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3594     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3595     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3596
3597     color = getPixelColor(device, 160, 360);
3598     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3599        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
3600     color = getPixelColor(device, 480, 360);
3601     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3602        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
3603     if(shader_20) {
3604         color = getPixelColor(device, 160, 120);
3605         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3606            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
3607     }
3608     if(shader_20_2) {
3609         color = getPixelColor(device, 480, 120);
3610         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3611            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3612     }
3613
3614     IDirect3DVertexDeclaration9_Release(decl);
3615     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
3616     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
3617     IDirect3DVertexShader9_Release(shader_11_2);
3618     IDirect3DVertexShader9_Release(shader_11);
3619 }
3620
3621 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
3622 {
3623     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
3624     HRESULT hr;
3625     DWORD color;
3626     DWORD shader_code_11[] =  {
3627         0xffff0101,                                         /* ps_1_1           */
3628         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3629         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3630         0x0000ffff                                          /* end              */
3631     };
3632     DWORD shader_code_12[] =  {
3633         0xffff0102,                                         /* ps_1_2           */
3634         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3635         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3636         0x0000ffff                                          /* end              */
3637     };
3638     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
3639      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
3640      * During development of this test, 1.3 shaders were verified too
3641      */
3642     DWORD shader_code_14[] =  {
3643         0xffff0104,                                         /* ps_1_4           */
3644         /* Try to make one constant local. It gets clamped too, although the binary contains
3645          * the bigger numbers
3646          */
3647         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
3648         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3649         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3650         0x0000ffff                                          /* end              */
3651     };
3652     DWORD shader_code_20[] =  {
3653         0xffff0200,                                         /* ps_2_0           */
3654         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
3655         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
3656         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
3657         0x0000ffff                                          /* end              */
3658     };
3659     float quad1[] = {
3660         -1.0,   -1.0,   0.1,
3661          0.0,   -1.0,   0.1,
3662         -1.0,    0.0,   0.1,
3663          0.0,    0.0,   0.1
3664     };
3665     float quad2[] = {
3666          0.0,   -1.0,   0.1,
3667          1.0,   -1.0,   0.1,
3668          0.0,    0.0,   0.1,
3669          1.0,    0.0,   0.1
3670     };
3671     float quad3[] = {
3672          0.0,    0.0,   0.1,
3673          1.0,    0.0,   0.1,
3674          0.0,    1.0,   0.1,
3675          1.0,    1.0,   0.1
3676     };
3677     float quad4[] = {
3678         -1.0,    0.0,   0.1,
3679          0.0,    0.0,   0.1,
3680         -1.0,    1.0,   0.1,
3681          0.0,    1.0,   0.1
3682     };
3683     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
3684     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
3685
3686     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3687     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3688
3689     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3690     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3691     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3692     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3693     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3694     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3695     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
3696     if(FAILED(hr)) shader_20 = NULL;
3697
3698     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3699     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3700     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3701     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3702     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3703     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3704
3705     hr = IDirect3DDevice9_BeginScene(device);
3706     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3707     if(SUCCEEDED(hr))
3708     {
3709         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3710         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3711         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3712         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3713
3714         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3715         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3716         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3717         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3718
3719         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3720         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3721         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3722         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3723
3724         if(shader_20) {
3725             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
3726             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3727             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3728             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3729         }
3730
3731         hr = IDirect3DDevice9_EndScene(device);
3732         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3733     }
3734     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3735     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3736
3737     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3739
3740     color = getPixelColor(device, 160, 360);
3741     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3742        "quad 1 has color %08x, expected 0x00808000\n", color);
3743     color = getPixelColor(device, 480, 360);
3744     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3745        "quad 2 has color %08x, expected 0x00808000\n", color);
3746     color = getPixelColor(device, 480, 120);
3747     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3748        "quad 3 has color %08x, expected 0x00808000\n", color);
3749     if(shader_20) {
3750         color = getPixelColor(device, 160, 120);
3751         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3752            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3753     }
3754
3755     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
3756     IDirect3DPixelShader9_Release(shader_14);
3757     IDirect3DPixelShader9_Release(shader_12);
3758     IDirect3DPixelShader9_Release(shader_11);
3759 }
3760
3761 static void cnd_test(IDirect3DDevice9 *device)
3762 {
3763     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
3764     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
3765     HRESULT hr;
3766     DWORD color;
3767     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
3768      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
3769      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
3770      */
3771     DWORD shader_code_11[] =  {
3772         0xffff0101,                                                                 /* ps_1_1               */
3773         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3774         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3775         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
3776         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3777         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3778         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3779         0x0000ffff                                                                  /* end                  */
3780     };
3781     DWORD shader_code_12[] =  {
3782         0xffff0102,                                                                 /* ps_1_2               */
3783         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3784         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3785         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3786         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
3787         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3788         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3789         0x0000ffff                                                                  /* end                  */
3790     };
3791     DWORD shader_code_13[] =  {
3792         0xffff0103,                                                                 /* ps_1_3               */
3793         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
3794         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
3795         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
3796         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
3797         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
3798         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
3799         0x0000ffff                                                                  /* end                  */
3800     };
3801     DWORD shader_code_14[] =  {
3802         0xffff0104,                                                                 /* ps_1_3               */
3803         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
3804         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
3805         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
3806         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
3807         0x0000ffff                                                                  /* end                  */
3808     };
3809
3810     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
3811      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
3812      * set by the compiler, it was added manually after compilation. It isn't always allowed,
3813      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
3814      * native CreatePixelShader returns an error.
3815      *
3816      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
3817      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
3818      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
3819      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
3820      */
3821     DWORD shader_code_11_coissue[] =  {
3822         0xffff0101,                                                             /* ps_1_1                   */
3823         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3824         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3825         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3826         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3827         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3828         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3829         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3830         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3831         /* 0x40000000 = D3DSI_COISSUE */
3832         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3833         0x0000ffff                                                              /* end                      */
3834     };
3835     DWORD shader_code_12_coissue[] =  {
3836         0xffff0102,                                                             /* ps_1_2                   */
3837         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3838         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3839         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3840         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3841         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3842         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3843         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3844         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3845         /* 0x40000000 = D3DSI_COISSUE */
3846         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3847         0x0000ffff                                                              /* end                      */
3848     };
3849     DWORD shader_code_13_coissue[] =  {
3850         0xffff0103,                                                             /* ps_1_3                   */
3851         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
3852         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3853         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
3854         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
3855         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
3856         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
3857         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
3858         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
3859         /* 0x40000000 = D3DSI_COISSUE */
3860         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
3861         0x0000ffff                                                              /* end                      */
3862     };
3863     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
3864      * compare against 0.5
3865      */
3866     DWORD shader_code_14_coissue[] =  {
3867         0xffff0104,                                                             /* ps_1_4                   */
3868         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
3869         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
3870         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
3871         /* 0x40000000 = D3DSI_COISSUE */
3872         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
3873         0x0000ffff                                                              /* end                      */
3874     };
3875     float quad1[] = {
3876         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
3877          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
3878         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
3879          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
3880     };
3881     float quad2[] = {
3882          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
3883          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
3884          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
3885          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
3886     };
3887     float quad3[] = {
3888          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
3889          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
3890          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
3891          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
3892     };
3893     float quad4[] = {
3894         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
3895          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
3896         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
3897          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
3898     };
3899     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
3900     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
3901     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
3902     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
3903
3904     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3905     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3906
3907     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3908     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3909     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3910     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3911     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
3912     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3913     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3914     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3915     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
3916     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3917     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
3918     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3919     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
3920     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3921     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
3922     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3923
3924     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3925     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3926     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3927     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3928     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3929     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3930
3931     hr = IDirect3DDevice9_BeginScene(device);
3932     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3933     if(SUCCEEDED(hr))
3934     {
3935         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3939
3940         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3941         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3943         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3944
3945         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
3946         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
3948         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3949
3950         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3951         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3953         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3954
3955         hr = IDirect3DDevice9_EndScene(device);
3956         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3957     }
3958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3959     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3960
3961     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3962     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3963
3964     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
3965     color = getPixelColor(device, 158, 118);
3966     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
3967     color = getPixelColor(device, 162, 118);
3968     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
3969     color = getPixelColor(device, 158, 122);
3970     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
3971     color = getPixelColor(device, 162, 122);
3972     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
3973
3974     /* 1.1 shader. All 3 components get set, based on the .w comparison */
3975     color = getPixelColor(device, 158, 358);
3976     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
3977     color = getPixelColor(device, 162, 358);
3978     ok(color == 0x00000000, "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
3979     color = getPixelColor(device, 158, 362);
3980     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
3981     color = getPixelColor(device, 162, 362);
3982     ok(color == 0x00000000, "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
3983
3984     /* 1.2 shader */
3985     color = getPixelColor(device, 478, 358);
3986     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
3987     color = getPixelColor(device, 482, 358);
3988     ok(color == 0x00000000, "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
3989     color = getPixelColor(device, 478, 362);
3990     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
3991     color = getPixelColor(device, 482, 362);
3992     ok(color == 0x00000000, "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
3993
3994     /* 1.3 shader */
3995     color = getPixelColor(device, 478, 118);
3996     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
3997     color = getPixelColor(device, 482, 118);
3998     ok(color == 0x00000000, "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
3999     color = getPixelColor(device, 478, 122);
4000     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4001     color = getPixelColor(device, 482, 122);
4002     ok(color == 0x00000000, "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4003
4004     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4005     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4006     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4007     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4008     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4009     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4010
4011     hr = IDirect3DDevice9_BeginScene(device);
4012     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4013     if(SUCCEEDED(hr))
4014     {
4015         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4016         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4017         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4018         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4019
4020         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4021         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4022         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4023         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4024
4025         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4026         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4027         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4028         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4029
4030         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4031         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4032         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4033         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4034
4035         hr = IDirect3DDevice9_EndScene(device);
4036         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4037     }
4038     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4040
4041     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4042      * that we swapped the values in c1 and c2 to make the other tests return some color
4043      */
4044     color = getPixelColor(device, 158, 118);
4045     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4046     color = getPixelColor(device, 162, 118);
4047     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4048     color = getPixelColor(device, 158, 122);
4049     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4050     color = getPixelColor(device, 162, 122);
4051     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4052
4053     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4054     color = getPixelColor(device, 158, 358);
4055     ok(color == 0x0000ff00, "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4056     color = getPixelColor(device, 162, 358);
4057     ok(color == 0x0000ff00, "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4058     color = getPixelColor(device, 158, 362);
4059     ok(color == 0x0000ff00, "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4060     color = getPixelColor(device, 162, 362);
4061     ok(color == 0x0000ff00, "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4062
4063     /* 1.2 shader */
4064     color = getPixelColor(device, 478, 358);
4065     ok(color == 0x0000ff00, "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4066     color = getPixelColor(device, 482, 358);
4067     ok(color == 0x0000ff00, "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4068     color = getPixelColor(device, 478, 362);
4069     ok(color == 0x0000ff00, "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4070     color = getPixelColor(device, 482, 362);
4071     ok(color == 0x0000ff00, "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4072
4073     /* 1.3 shader */
4074     color = getPixelColor(device, 478, 118);
4075     ok(color == 0x0000ff00, "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4076     color = getPixelColor(device, 482, 118);
4077     ok(color == 0x0000ff00, "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4078     color = getPixelColor(device, 478, 122);
4079     ok(color == 0x0000ff00, "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4080     color = getPixelColor(device, 482, 122);
4081     ok(color == 0x0000ff00, "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4082
4083     IDirect3DPixelShader9_Release(shader_14_coissue);
4084     IDirect3DPixelShader9_Release(shader_13_coissue);
4085     IDirect3DPixelShader9_Release(shader_12_coissue);
4086     IDirect3DPixelShader9_Release(shader_11_coissue);
4087     IDirect3DPixelShader9_Release(shader_14);
4088     IDirect3DPixelShader9_Release(shader_13);
4089     IDirect3DPixelShader9_Release(shader_12);
4090     IDirect3DPixelShader9_Release(shader_11);
4091 }
4092
4093 static void nested_loop_test(IDirect3DDevice9 *device) {
4094     const DWORD shader_code[] = {
4095         0xffff0300,                                                             /* ps_3_0               */
4096         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4097         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4098         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4099         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4100         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4101         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4102         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4103         0x0000001d,                                                             /* endloop              */
4104         0x0000001d,                                                             /* endloop              */
4105         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4106         0x0000ffff                                                              /* end                  */
4107     };
4108     IDirect3DPixelShader9 *shader;
4109     HRESULT hr;
4110     DWORD color;
4111     const float quad[] = {
4112         -1.0,   -1.0,   0.1,
4113          1.0,   -1.0,   0.1,
4114         -1.0,    1.0,   0.1,
4115          1.0,    1.0,   0.1
4116     };
4117
4118     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4119     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4120     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4121     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4122     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4123     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4124     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4125     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4126
4127     hr = IDirect3DDevice9_BeginScene(device);
4128     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4129     if(SUCCEEDED(hr))
4130     {
4131         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4132         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4133         hr = IDirect3DDevice9_EndScene(device);
4134         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4135     }
4136     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4137     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4138
4139     color = getPixelColor(device, 360, 240);
4140     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4141        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4142
4143     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4145     IDirect3DPixelShader9_Release(shader);
4146 }
4147
4148 struct varying_test_struct
4149 {
4150     const DWORD             *shader_code;
4151     IDirect3DPixelShader9   *shader;
4152     DWORD                   color, color_rhw;
4153     const char              *name;
4154     BOOL                    todo, todo_rhw;
4155 };
4156
4157 struct hugeVertex
4158 {
4159     float pos_x,        pos_y,      pos_z,      rhw;
4160     float weight_1,     weight_2,   weight_3,   weight_4;
4161     float index_1,      index_2,    index_3,    index_4;
4162     float normal_1,     normal_2,   normal_3,   normal_4;
4163     float fog_1,        fog_2,      fog_3,      fog_4;
4164     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
4165     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
4166     float binormal_1,   binormal_2, binormal_3, binormal_4;
4167     float depth_1,      depth_2,    depth_3,    depth_4;
4168     DWORD diffuse, specular;
4169 };
4170
4171 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
4172     /* dcl_position: fails to compile */
4173     const DWORD blendweight_code[] = {
4174         0xffff0300,                             /* ps_3_0                   */
4175         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
4176         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4177         0x0000ffff                              /* end                      */
4178     };
4179     const DWORD blendindices_code[] = {
4180         0xffff0300,                             /* ps_3_0                   */
4181         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
4182         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4183         0x0000ffff                              /* end                      */
4184     };
4185     const DWORD normal_code[] = {
4186         0xffff0300,                             /* ps_3_0                   */
4187         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
4188         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4189         0x0000ffff                              /* end                      */
4190     };
4191     /* psize: fails? */
4192     const DWORD texcoord0_code[] = {
4193         0xffff0300,                             /* ps_3_0                   */
4194         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
4195         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4196         0x0000ffff                              /* end                      */
4197     };
4198     const DWORD tangent_code[] = {
4199         0xffff0300,                             /* ps_3_0                   */
4200         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
4201         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4202         0x0000ffff                              /* end                      */
4203     };
4204     const DWORD binormal_code[] = {
4205         0xffff0300,                             /* ps_3_0                   */
4206         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
4207         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4208         0x0000ffff                              /* end                      */
4209     };
4210     /* tessfactor: fails */
4211     /* positiont: fails */
4212     const DWORD color_code[] = {
4213         0xffff0300,                             /* ps_3_0                   */
4214         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
4215         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4216         0x0000ffff                              /* end                      */
4217     };
4218     const DWORD fog_code[] = {
4219         0xffff0300,                             /* ps_3_0                   */
4220         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
4221         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4222         0x0000ffff                              /* end                      */
4223     };
4224     const DWORD depth_code[] = {
4225         0xffff0300,                             /* ps_3_0                   */
4226         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
4227         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4228         0x0000ffff                              /* end                      */
4229     };
4230     const DWORD specular_code[] = {
4231         0xffff0300,                             /* ps_3_0                   */
4232         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
4233         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
4234         0x0000ffff                              /* end                      */
4235     };
4236     /* sample: fails */
4237
4238     struct varying_test_struct tests[] = {
4239        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
4240        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
4241        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
4242        /* Why does dx not forward the texcoord? */
4243        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
4244        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
4245        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
4246        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
4247        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
4248        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
4249        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
4250     };
4251     /* Declare a monster vertex type :-) */
4252     static const D3DVERTEXELEMENT9 decl_elements[] = {
4253         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
4254         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
4255         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
4256         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
4257         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
4258         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
4259         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
4260         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
4261         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
4262         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
4263         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
4264         D3DDECL_END()
4265     };
4266     static const D3DVERTEXELEMENT9 decl_elements2[] = {
4267         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
4268         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
4269         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
4270         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
4271         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
4272         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
4273         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
4274         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
4275         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
4276         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
4277         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
4278         D3DDECL_END()
4279     };
4280     struct hugeVertex data[4] = {
4281         {
4282             -1.0,   -1.0,   0.1,    1.0,
4283              0.1,    0.1,   0.1,    0.1,
4284              0.2,    0.2,   0.2,    0.2,
4285              0.3,    0.3,   0.3,    0.3,
4286              0.4,    0.4,   0.4,    0.4,
4287              0.50,   0.55,  0.55,   0.55,
4288              0.6,    0.6,   0.6,    0.7,
4289              0.7,    0.7,   0.7,    0.6,
4290              0.8,    0.8,   0.8,    0.8,
4291              0xe6e6e6e6, /* 0.9 * 256 */
4292              0x224488ff  /* Nothing special */
4293         },
4294         {
4295              1.0,   -1.0,   0.1,    1.0,
4296              0.1,    0.1,   0.1,    0.1,
4297              0.2,    0.2,   0.2,    0.2,
4298              0.3,    0.3,   0.3,    0.3,
4299              0.4,    0.4,   0.4,    0.4,
4300              0.50,   0.55,  0.55,   0.55,
4301              0.6,    0.6,   0.6,    0.7,
4302              0.7,    0.7,   0.7,    0.6,
4303              0.8,    0.8,   0.8,    0.8,
4304              0xe6e6e6e6, /* 0.9 * 256 */
4305              0x224488ff /* Nothing special */
4306         },
4307         {
4308             -1.0,    1.0,   0.1,    1.0,
4309              0.1,    0.1,   0.1,    0.1,
4310              0.2,    0.2,   0.2,    0.2,
4311              0.3,    0.3,   0.3,    0.3,
4312              0.4,    0.4,   0.4,    0.4,
4313              0.50,   0.55,  0.55,   0.55,
4314              0.6,    0.6,   0.6,    0.7,
4315              0.7,    0.7,   0.7,    0.6,
4316              0.8,    0.8,   0.8,    0.8,
4317              0xe6e6e6e6, /* 0.9 * 256 */
4318              0x224488ff /* Nothing special */
4319         },
4320         {
4321              1.0,    1.0,   0.1,    1.0,
4322              0.1,    0.1,   0.1,    0.1,
4323              0.2,    0.2,   0.2,    0.2,
4324              0.3,    0.3,   0.3,    0.3,
4325              0.4,    0.4,   0.4,    0.4,
4326              0.50,   0.55,  0.55,   0.55,
4327              0.6,    0.6,   0.6,    0.7,
4328              0.7,    0.7,   0.7,    0.6,
4329              0.8,    0.8,   0.8,    0.8,
4330              0xe6e6e6e6, /* 0.9 * 256 */
4331              0x224488ff /* Nothing special */
4332         },
4333     };
4334     struct hugeVertex data2[4];
4335     IDirect3DVertexDeclaration9 *decl;
4336     IDirect3DVertexDeclaration9 *decl2;
4337     HRESULT hr;
4338     unsigned int i;
4339     DWORD color, r, g, b, r_e, g_e, b_e;
4340
4341     memcpy(data2, data, sizeof(data2));
4342     data2[0].pos_x = 0;     data2[0].pos_y = 0;
4343     data2[1].pos_x = 640;   data2[1].pos_y = 0;
4344     data2[2].pos_x = 0;     data2[2].pos_y = 480;
4345     data2[3].pos_x = 640;   data2[3].pos_y = 480;
4346
4347     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4348     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4349     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4350     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4351     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4352     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4353
4354     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4355     {
4356         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
4357         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
4358            tests[i].name, DXGetErrorString9(hr));
4359     }
4360
4361     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4362     {
4363         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4364         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4365
4366         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4367         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4368
4369         hr = IDirect3DDevice9_BeginScene(device);
4370         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4371         if(SUCCEEDED(hr))
4372         {
4373             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
4374             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4375             hr = IDirect3DDevice9_EndScene(device);
4376             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4377         }
4378         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4379         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4380
4381         color = getPixelColor(device, 360, 240);
4382         r = color & 0x00ff0000 >> 16;
4383         g = color & 0x0000ff00 >>  8;
4384         b = color & 0x000000ff;
4385         r_e = tests[i].color & 0x00ff0000 >> 16;
4386         g_e = tests[i].color & 0x0000ff00 >>  8;
4387         b_e = tests[i].color & 0x000000ff;
4388
4389         if(tests[i].todo) {
4390             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4391                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4392                          tests[i].name, color, tests[i].color);
4393         } else {
4394             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4395                "Test %s returned color 0x%08x, expected 0x%08x\n",
4396                tests[i].name, color, tests[i].color);
4397         }
4398     }
4399
4400     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4401     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4402     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4403     {
4404         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4405         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4406
4407         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4408         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4409
4410         hr = IDirect3DDevice9_BeginScene(device);
4411         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4412         if(SUCCEEDED(hr))
4413         {
4414             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
4415             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4416             hr = IDirect3DDevice9_EndScene(device);
4417             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4418         }
4419         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4420         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4421
4422         color = getPixelColor(device, 360, 240);
4423         r = color & 0x00ff0000 >> 16;
4424         g = color & 0x0000ff00 >>  8;
4425         b = color & 0x000000ff;
4426         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
4427         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
4428         b_e = tests[i].color_rhw & 0x000000ff;
4429
4430         if(tests[i].todo_rhw) {
4431             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
4432              * pipeline
4433              */
4434             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4435                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4436                          tests[i].name, color, tests[i].color_rhw);
4437         } else {
4438             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4439                "Test %s returned color 0x%08x, expected 0x%08x\n",
4440                tests[i].name, color, tests[i].color_rhw);
4441         }
4442     }
4443
4444     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4445     {
4446         IDirect3DPixelShader9_Release(tests[i].shader);
4447     }
4448
4449     IDirect3DVertexDeclaration9_Release(decl2);
4450     IDirect3DVertexDeclaration9_Release(decl);
4451 }
4452
4453 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
4454     static const DWORD ps_code[] = {
4455     0xffff0300,                                                             /* ps_3_0                       */
4456     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
4457     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
4458     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
4459     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
4460     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
4461     0x0200001f, 0x80000003, 0x900f0006,
4462     0x0200001f, 0x80000006, 0x900f0007,
4463     0x0200001f, 0x80000001, 0x900f0008,
4464     0x0200001f, 0x8000000c, 0x900f0009,
4465
4466     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4467     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
4468     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
4469     0x0000001d,                                                             /* endloop                      */
4470     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4471     0x0000ffff                                                              /* end                          */
4472     };
4473     static const DWORD vs_1_code[] = {
4474     0xfffe0101,                                                             /* vs_1_1                       */
4475     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4476     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
4477     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
4478     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
4479     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4480     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
4481     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
4482     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
4483     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
4484     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
4485     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
4486     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
4487     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
4488     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
4489     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
4490     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
4491     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
4492     0x0000ffff
4493     };
4494     DWORD vs_2_code[] = {
4495     0xfffe0200,                                                             /* vs_2_0                       */
4496     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4497     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
4498     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0   */
4499     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0   */
4500     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4501     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
4502     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
4503     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
4504     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
4505     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
4506     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
4507     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
4508     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
4509     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
4510     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
4511     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
4512     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
4513     0x0000ffff                                                              /* end                          */
4514     };
4515     /* TODO: Define normal, tangent, blendweight and depth here */
4516     static const DWORD vs_3_code[] = {
4517     0xfffe0300,                                                             /* vs_3_0                       */
4518     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4519     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
4520     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
4521     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
4522     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
4523     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
4524     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
4525     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
4526     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
4527     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
4528     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
4529     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
4530     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
4531     0x0000ffff                                                              /* end                          */
4532     };
4533     float quad1[] =  {
4534         -1.0,   -1.0,   0.1,
4535          0.0,   -1.0,   0.1,
4536         -1.0,    0.0,   0.1,
4537          0.0,    0.0,   0.1
4538     };
4539     float quad2[] =  {
4540          0.0,   -1.0,   0.1,
4541          1.0,   -1.0,   0.1,
4542          0.0,    0.0,   0.1,
4543          1.0,    0.0,   0.1
4544     };
4545     float quad3[] =  {
4546         -1.0,    0.0,   0.1,
4547          0.0,    0.0,   0.1,
4548         -1.0,    1.0,   0.1,
4549          0.0,    1.0,   0.1
4550     };
4551
4552     HRESULT hr;
4553     DWORD color;
4554     IDirect3DPixelShader9 *pixelshader = NULL;
4555     IDirect3DVertexShader9 *vs_1_shader = NULL;
4556     IDirect3DVertexShader9 *vs_2_shader = NULL;
4557     IDirect3DVertexShader9 *vs_3_shader = NULL;
4558
4559     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
4560
4561     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
4562     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4563     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
4564     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4565     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
4566     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4567     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
4568     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4569     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
4570     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4571     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4572
4573     hr = IDirect3DDevice9_BeginScene(device);
4574     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4575     if(SUCCEEDED(hr))
4576     {
4577         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
4578         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4579         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4580         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4581
4582         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
4583         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4584         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4585         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4586
4587         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
4588         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4589         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4590         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4591
4592         hr = IDirect3DDevice9_EndScene(device);
4593         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4594     }
4595     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4596     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4597
4598     color = getPixelColor(device, 160, 120);
4599     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4600        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
4601        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4602        "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
4603     color = getPixelColor(device, 160, 360);
4604     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4605        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4606        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4607        "vs_1_1 returned color 0x%08x, expected 0x00808080\n", color);
4608     color = getPixelColor(device, 480, 360);
4609     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4610        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4611        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4612        "vs_2_0 returned color 0x%08x, expected 0x00000000\n", color);
4613
4614     /* cleanup */
4615     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4616     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4617     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4618     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4619     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
4620     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
4621     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
4622     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
4623 }
4624
4625 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
4626     static const DWORD vs_code[] = {
4627     0xfffe0300,                                                             /* vs_3_0                       */
4628     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
4629     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
4630     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
4631     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
4632     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
4633     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
4634     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
4635     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
4636     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
4637     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
4638     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
4639     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
4640     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
4641
4642     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
4643     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
4644     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
4645     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
4646     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
4647     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
4648     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
4649     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
4650     0x0000ffff                                                              /* end                          */
4651     };
4652     static const DWORD ps_1_code[] = {
4653     0xffff0104,                                                             /* ps_1_4                       */
4654     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
4655     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
4656     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
4657     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
4658     0x0000ffff                                                              /* end                          */
4659     };
4660     static const DWORD ps_2_code[] = {
4661     0xffff0200,                                                             /* ps_2_0                       */
4662     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
4663     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
4664     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
4665
4666     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
4667     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
4668     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4669     0x0000ffff                                                              /* end                          */
4670     };
4671     static const DWORD ps_3_code[] = {
4672     0xffff0300,                                                             /* ps_3_0                       */
4673     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
4674     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
4675     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
4676
4677     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
4678     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
4679     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
4680     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4681     0x0000ffff                                                              /* end                          */
4682     };
4683
4684     float quad1[] =  {
4685         -1.0,   -1.0,   0.1,
4686          0.0,   -1.0,   0.1,
4687         -1.0,    0.0,   0.1,
4688          0.0,    0.0,   0.1
4689     };
4690     float quad2[] =  {
4691          0.0,   -1.0,   0.1,
4692          1.0,   -1.0,   0.1,
4693          0.0,    0.0,   0.1,
4694          1.0,    0.0,   0.1
4695     };
4696     float quad3[] =  {
4697         -1.0,    0.0,   0.1,
4698          0.0,    0.0,   0.1,
4699         -1.0,    1.0,   0.1,
4700          0.0,    1.0,   0.1
4701     };
4702     float quad4[] =  {
4703          0.0,    0.0,   0.1,
4704          1.0,    0.0,   0.1,
4705          0.0,    1.0,   0.1,
4706          1.0,    1.0,   0.1
4707     };
4708
4709     HRESULT hr;
4710     DWORD color;
4711     IDirect3DVertexShader9 *vertexshader = NULL;
4712     IDirect3DPixelShader9 *ps_1_shader = NULL;
4713     IDirect3DPixelShader9 *ps_2_shader = NULL;
4714     IDirect3DPixelShader9 *ps_3_shader = NULL;
4715     IDirect3DTexture9 *texture = NULL;
4716     D3DLOCKED_RECT lr;
4717     unsigned int x, y;
4718
4719     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4720
4721     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
4722     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4723     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4724     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
4725     for(y = 0; y < 512; y++) {
4726         for(x = 0; x < 512; x++) {
4727             double r_f = (double) x / (double) 512;
4728             double g_f = (double) y / (double) 512;
4729             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
4730             unsigned short r = (unsigned short) (r_f * 65535.0);
4731             unsigned short g = (unsigned short) (g_f * 65535.0);
4732             dst[0] = r;
4733             dst[1] = g;
4734             dst[2] = 0;
4735             dst[3] = 65535;
4736         }
4737     }
4738     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4739     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4740
4741     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
4742     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4743     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
4744     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4745     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
4746     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4747     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
4748     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4749     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
4750     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4751     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4752
4753     hr = IDirect3DDevice9_BeginScene(device);
4754     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4755     if(SUCCEEDED(hr))
4756     {
4757         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
4758         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4759         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4760         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4761
4762         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
4763         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4764         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4765         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4766
4767         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
4768         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4769         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4770         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4771
4772         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4773         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4774         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4775         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4776         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4777         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
4778         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4779         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
4780         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
4781         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4782
4783         hr = IDirect3DDevice9_EndScene(device);
4784         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4785     }
4786     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4787     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4788
4789     color = getPixelColor(device, 160, 120);
4790     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
4791        (color & 0x0000ff00) == 0x0000ff00 &&
4792        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
4793        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
4794     color = getPixelColor(device, 160, 360);
4795     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4796        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
4797        (color & 0x000000ff) == 0x00000000,
4798        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
4799     color = getPixelColor(device, 480, 360);
4800     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4801        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4802        (color & 0x000000ff) == 0x00000000,
4803        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
4804     color = getPixelColor(device, 480, 160);
4805     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4806        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4807        (color & 0x000000ff) == 0x00000000,
4808        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
4809
4810     /* cleanup */
4811     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4812     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4813     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4814     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4815     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4816     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4817     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
4818     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
4819     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
4820     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
4821     if(texture) IDirect3DTexture9_Release(texture);
4822 }
4823
4824 void test_compare_instructions(IDirect3DDevice9 *device)
4825 {
4826     DWORD shader_sge_vec_code[] = {
4827         0xfffe0101,                                         /* vs_1_1                   */
4828         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4829         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4830         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4831         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
4832         0x0000ffff                                          /* end                      */
4833     };
4834     DWORD shader_slt_vec_code[] = {
4835         0xfffe0101,                                         /* vs_1_1                   */
4836         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4837         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4838         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4839         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
4840         0x0000ffff                                          /* end                      */
4841     };
4842     DWORD shader_sge_scalar_code[] = {
4843         0xfffe0101,                                         /* vs_1_1                   */
4844         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4845         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4846         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4847         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
4848         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
4849         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
4850         0x0000ffff                                          /* end                      */
4851     };
4852     DWORD shader_slt_scalar_code[] = {
4853         0xfffe0101,                                         /* vs_1_1                   */
4854         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
4855         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
4856         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
4857         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
4858         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
4859         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
4860         0x0000ffff                                          /* end                      */
4861     };
4862     IDirect3DVertexShader9 *shader_sge_vec;
4863     IDirect3DVertexShader9 *shader_slt_vec;
4864     IDirect3DVertexShader9 *shader_sge_scalar;
4865     IDirect3DVertexShader9 *shader_slt_scalar;
4866     HRESULT hr, color;
4867     float quad1[] =  {
4868         -1.0,   -1.0,   0.1,
4869          0.0,   -1.0,   0.1,
4870         -1.0,    0.0,   0.1,
4871          0.0,    0.0,   0.1
4872     };
4873     float quad2[] =  {
4874          0.0,   -1.0,   0.1,
4875          1.0,   -1.0,   0.1,
4876          0.0,    0.0,   0.1,
4877          1.0,    0.0,   0.1
4878     };
4879     float quad3[] =  {
4880         -1.0,    0.0,   0.1,
4881          0.0,    0.0,   0.1,
4882         -1.0,    1.0,   0.1,
4883          0.0,    1.0,   0.1
4884     };
4885     float quad4[] =  {
4886          0.0,    0.0,   0.1,
4887          1.0,    0.0,   0.1,
4888          0.0,    1.0,   0.1,
4889          1.0,    1.0,   0.1
4890     };
4891     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
4892     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
4893
4894     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4895
4896     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
4897     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4898     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
4899     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4900     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
4901     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4902     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
4903     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4904     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
4905     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4906     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
4907     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4908     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4909     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4910
4911     hr = IDirect3DDevice9_BeginScene(device);
4912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4913     if(SUCCEEDED(hr))
4914     {
4915         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
4916         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4917         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4918         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4919
4920         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
4921         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4922         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
4923         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4924
4925         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
4926         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4927         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4928         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4929
4930         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
4931         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4932
4933         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
4934         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4935         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
4936         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4937
4938         hr = IDirect3DDevice9_EndScene(device);
4939         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4940     }
4941
4942     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4943     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4944
4945     color = getPixelColor(device, 160, 360);
4946     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
4947     color = getPixelColor(device, 480, 360);
4948     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
4949     color = getPixelColor(device, 160, 120);
4950     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
4951     color = getPixelColor(device, 480, 160);
4952     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
4953
4954     IDirect3DVertexShader9_Release(shader_sge_vec);
4955     IDirect3DVertexShader9_Release(shader_slt_vec);
4956     IDirect3DVertexShader9_Release(shader_sge_scalar);
4957     IDirect3DVertexShader9_Release(shader_slt_scalar);
4958 }
4959
4960 void test_vshader_input(IDirect3DDevice9 *device)
4961 {
4962     DWORD swapped_shader_code_3[] = {
4963         0xfffe0300,                                         /* vs_3_0               */
4964         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
4965         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
4966         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4967         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
4968         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
4969         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
4970         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
4971         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
4972         0x0000ffff                                          /* end                  */
4973     };
4974     DWORD swapped_shader_code_1[] = {
4975         0xfffe0101,                                         /* vs_1_1               */
4976         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4977         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
4978         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
4979         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
4980         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
4981         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
4982         0x0000ffff                                          /* end                  */
4983     };
4984     DWORD swapped_shader_code_2[] = {
4985         0xfffe0200,                                         /* vs_2_0               */
4986         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4987         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
4988         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
4989         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
4990         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
4991         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
4992         0x0000ffff                                          /* end                  */
4993     };
4994     DWORD texcoord_color_shader_code_3[] = {
4995         0xfffe0300,                                         /* vs_3_0               */
4996         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
4997         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
4998         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
4999         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5000         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5001         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5002         0x0000ffff                                          /* end                  */
5003     };
5004     DWORD texcoord_color_shader_code_2[] = {
5005         0xfffe0200,                                         /* vs_2_0               */
5006         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5007         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5008         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5009         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5010         0x0000ffff                                          /* end                  */
5011     };
5012     DWORD texcoord_color_shader_code_1[] = {
5013         0xfffe0101,                                         /* vs_1_1               */
5014         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5015         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5016         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5017         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5018         0x0000ffff                                          /* end                  */
5019     };
5020     DWORD color_color_shader_code_3[] = {
5021         0xfffe0300,                                         /* vs_3_0               */
5022         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5023         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5024         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5025         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5026         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5027         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5028         0x0000ffff                                          /* end                  */
5029     };
5030     DWORD color_color_shader_code_2[] = {
5031         0xfffe0200,                                         /* vs_2_0               */
5032         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5033         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5034         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5035         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5036         0x0000ffff                                          /* end                  */
5037     };
5038     DWORD color_color_shader_code_1[] = {
5039         0xfffe0101,                                         /* vs_1_1               */
5040         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5041         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5042         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5043         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5044         0x0000ffff                                          /* end                  */
5045     };
5046     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5047     HRESULT hr;
5048     DWORD color, r, g, b;
5049     float quad1[] =  {
5050         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5051          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5052         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5053          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5054     };
5055     float quad2[] =  {
5056          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5057          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5058          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5059          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5060     };
5061     float quad3[] =  {
5062         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5063          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5064         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5065          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5066     };
5067     float quad4[] =  {
5068          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5069          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5070          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5071          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5072     };
5073     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5074         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5075         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5076         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5077         D3DDECL_END()
5078     };
5079     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5080         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5081         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5082         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5083         D3DDECL_END()
5084     };
5085     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5086         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5087         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5088         D3DDECL_END()
5089     };
5090     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5091         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5092         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5093         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5094         D3DDECL_END()
5095     };
5096     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5097         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5098         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5099         D3DDECL_END()
5100     };
5101     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5102         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5103         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5104         D3DDECL_END()
5105     };
5106     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5107         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5108         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5109         D3DDECL_END()
5110     };
5111     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5112         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5113         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5114         D3DDECL_END()
5115     };
5116     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5117     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5118     unsigned int i;
5119     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5120     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5121
5122     struct vertex quad1_color[] =  {
5123        {-1.0,   -1.0,   0.1,    0x00ff8040},
5124        { 0.0,   -1.0,   0.1,    0x00ff8040},
5125        {-1.0,    0.0,   0.1,    0x00ff8040},
5126        { 0.0,    0.0,   0.1,    0x00ff8040}
5127     };
5128     struct vertex quad2_color[] =  {
5129        { 0.0,   -1.0,   0.1,    0x00ff8040},
5130        { 1.0,   -1.0,   0.1,    0x00ff8040},
5131        { 0.0,    0.0,   0.1,    0x00ff8040},
5132        { 1.0,    0.0,   0.1,    0x00ff8040}
5133     };
5134     struct vertex quad3_color[] =  {
5135        {-1.0,    0.0,   0.1,    0x00ff8040},
5136        { 0.0,    0.0,   0.1,    0x00ff8040},
5137        {-1.0,    1.0,   0.1,    0x00ff8040},
5138        { 0.0,    1.0,   0.1,    0x00ff8040}
5139     };
5140     float quad4_color[] =  {
5141          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5142          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5143          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5144          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5145     };
5146
5147     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
5148     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5149     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
5150     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5151     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
5152     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5153     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
5154     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5155
5156     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
5157     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5158     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
5159     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5160     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
5161     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5162     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
5163     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5164
5165     for(i = 1; i <= 3; i++) {
5166         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5167         if(i == 3) {
5168             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
5169             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5170         } else if(i == 2){
5171             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
5172             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5173         } else if(i == 1) {
5174             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
5175             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5176         }
5177
5178         hr = IDirect3DDevice9_BeginScene(device);
5179         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5180         if(SUCCEEDED(hr))
5181         {
5182             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5183             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5184
5185             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5186             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5187             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
5188             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5189
5190             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5191             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5192             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
5193             if(i == 3 || i == 2) {
5194                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5195             } else if(i == 1) {
5196                 /* Succeeds or fails, depending on SW or HW vertex processing */
5197                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5198             }
5199
5200             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
5201             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5202             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
5203             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5204
5205             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
5206             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5207             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
5208             if(i == 3 || i == 2) {
5209                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5210             } else if(i == 1) {
5211                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
5212             }
5213
5214             hr = IDirect3DDevice9_EndScene(device);
5215             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5216         }
5217
5218         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5219         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5220
5221         if(i == 3 || i == 2) {
5222             color = getPixelColor(device, 160, 360);
5223             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5224                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5225
5226             /* The last value of the read but undefined stream is used */
5227             color = getPixelColor(device, 480, 360);
5228             ok(color == 0x00FFFF00, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5229             color = getPixelColor(device, 160, 120);
5230             ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081,
5231                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5232
5233             color = getPixelColor(device, 480, 160);
5234             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5235         } else if(i == 1) {
5236             color = getPixelColor(device, 160, 360);
5237             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5238                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5239             color = getPixelColor(device, 480, 360);
5240             /* Accept the clear color as well in this case, since SW VP returns an error */
5241             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5242             color = getPixelColor(device, 160, 120);
5243             ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
5244                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5245             color = getPixelColor(device, 480, 160);
5246             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5247         }
5248
5249         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
5250         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5251
5252         /* Now find out if the whole streams are re-read, or just the last active value for the
5253          * vertices is used.
5254          */
5255         hr = IDirect3DDevice9_BeginScene(device);
5256         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5257         if(SUCCEEDED(hr))
5258         {
5259             float quad1_modified[] =  {
5260                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5261                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
5262                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
5263                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
5264             };
5265             float quad2_modified[] =  {
5266                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5267                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5268                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5269                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5270             };
5271
5272             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5273             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5274
5275             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5276             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5277             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
5278             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5279
5280             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5281             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5282             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
5283             if(i == 3 || i == 2) {
5284                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5285             } else if(i == 1) {
5286                 /* Succeeds or fails, depending on SW or HW vertex processing */
5287                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5288             }
5289
5290             hr = IDirect3DDevice9_EndScene(device);
5291             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5292         }
5293         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5294         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5295
5296         color = getPixelColor(device, 480, 360);
5297         /* vs_1_1 may fail, accept the clear color
5298          *
5299          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
5300          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
5301          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
5302          * refrast's result.
5303          *
5304          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
5305          */
5306         ok(color == 0x000000FF || color == 0x00808080,
5307            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF\n", color);
5308         color = getPixelColor(device, 160, 120);
5309
5310         IDirect3DDevice9_SetVertexShader(device, NULL);
5311         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5312
5313         IDirect3DVertexShader9_Release(swapped_shader);
5314     }
5315
5316     for(i = 1; i <= 3; i++) {
5317         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5318         if(i == 3) {
5319             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
5320             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5321             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
5322             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5323         } else if(i == 2){
5324             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
5325             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5326             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
5327             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5328         } else if(i == 1) {
5329             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
5330             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5331             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
5332             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5333         }
5334
5335         hr = IDirect3DDevice9_BeginScene(device);
5336         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5337         if(SUCCEEDED(hr))
5338         {
5339             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
5340             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5341             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
5342             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5343             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
5344             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5345
5346             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
5347             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5348
5349             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
5350             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5351             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
5352             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5353             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
5354             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5355
5356             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
5357             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5358             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
5359             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5360             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
5361             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5362
5363             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
5364             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5365             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
5366             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5367
5368             hr = IDirect3DDevice9_EndScene(device);
5369             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5370         }
5371         IDirect3DDevice9_SetVertexShader(device, NULL);
5372         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5373
5374         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5375         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5376
5377         color = getPixelColor(device, 160, 360);
5378         r = (color & 0x00ff0000) >> 16;
5379         g = (color & 0x0000ff00) >>  8;
5380         b = (color & 0x000000ff) >>  0;
5381         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5382            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
5383         color = getPixelColor(device, 480, 360);
5384         r = (color & 0x00ff0000) >> 16;
5385         g = (color & 0x0000ff00) >>  8;
5386         b = (color & 0x000000ff) >>  0;
5387         ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
5388            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
5389         color = getPixelColor(device, 160, 120);
5390         r = (color & 0x00ff0000) >> 16;
5391         g = (color & 0x0000ff00) >>  8;
5392         b = (color & 0x000000ff) >>  0;
5393         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5394            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
5395         color = getPixelColor(device, 480, 160);
5396         r = (color & 0x00ff0000) >> 16;
5397         g = (color & 0x0000ff00) >>  8;
5398         b = (color & 0x000000ff) >>  0;
5399         ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
5400            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
5401
5402         IDirect3DVertexShader9_Release(texcoord_color_shader);
5403         IDirect3DVertexShader9_Release(color_color_shader);
5404     }
5405
5406     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
5407     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
5408     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
5409     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
5410
5411     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
5412     IDirect3DVertexDeclaration9_Release(decl_color_color);
5413     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
5414     IDirect3DVertexDeclaration9_Release(decl_color_float);
5415 }
5416
5417 static void srgbtexture_test(IDirect3DDevice9 *device)
5418 {
5419     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
5420      * texture stage state to render a quad using that texture.  The resulting
5421      * color components should be 0x36 (~ 0.21), per this formula:
5422      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
5423      * This is true where srgb_color > 0.04045.
5424      */
5425     IDirect3D9 *d3d = NULL;
5426     HRESULT hr;
5427     LPDIRECT3DTEXTURE9 texture = NULL;
5428     LPDIRECT3DSURFACE9 surface = NULL;
5429     D3DLOCKED_RECT lr;
5430     DWORD color;
5431     float quad[] = {
5432         -1.0,       1.0,       0.0,     0.0,    0.0,
5433          1.0,       1.0,       0.0,     1.0,    0.0,
5434         -1.0,      -1.0,       0.0,     0.0,    1.0,
5435          1.0,      -1.0,       0.0,     1.0,    1.0,
5436     };
5437
5438
5439     memset(&lr, 0, sizeof(lr));
5440     IDirect3DDevice9_GetDirect3D(device, &d3d);
5441     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5442                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
5443                                     D3DFMT_A8R8G8B8) != D3D_OK) {
5444         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
5445         goto out;
5446     }
5447
5448     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
5449                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
5450                                         &texture, NULL);
5451     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
5452     if(!texture) {
5453         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
5454         goto out;
5455     }
5456     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5457     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
5458
5459     fill_surface(surface, 0xff7f7f7f);
5460     IDirect3DSurface9_Release(surface);
5461
5462     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5463     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5464     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5465     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
5466
5467     hr = IDirect3DDevice9_BeginScene(device);
5468     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
5469     if(SUCCEEDED(hr))
5470     {
5471         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
5472         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
5473
5474         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5475         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
5476
5477
5478         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5479         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
5480
5481         hr = IDirect3DDevice9_EndScene(device);
5482         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
5483     }
5484
5485     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5486     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
5487     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
5488     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
5489
5490     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5491     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5492
5493     color = getPixelColor(device, 320, 240);
5494     ok(color == 0x00363636, "srgb quad has color %08x, expected 0x00363636\n", color);
5495
5496 out:
5497     if(texture) IDirect3DTexture9_Release(texture);
5498     IDirect3D9_Release(d3d);
5499 }
5500
5501 static void shademode_test(IDirect3DDevice9 *device)
5502 {
5503     /* Render a quad and try all of the different fixed function shading models. */
5504     HRESULT hr;
5505     DWORD color0, color1;
5506     DWORD shademode = D3DSHADE_FLAT;
5507     DWORD primtype = D3DPT_TRIANGLESTRIP;
5508     LPVOID data = NULL;
5509     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
5510     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
5511     UINT i, j;
5512     struct vertex quad_strip[] =
5513     {
5514         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
5515         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
5516         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
5517         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
5518     };
5519     struct vertex quad_list[] =
5520     {
5521         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
5522         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
5523         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
5524
5525         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
5526         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
5527         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
5528     };
5529
5530     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
5531                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
5532     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
5533     if (FAILED(hr)) goto bail;
5534
5535     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
5536                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
5537     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
5538     if (FAILED(hr)) goto bail;
5539
5540     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5541     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5542
5543     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
5544     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
5545
5546     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
5547     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5548     memcpy(data, quad_strip, sizeof(quad_strip));
5549     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
5550     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
5551
5552     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
5553     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5554     memcpy(data, quad_list, sizeof(quad_list));
5555     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
5556     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
5557
5558     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
5559      * the color fixups we have to do for FLAT shading will be dependent on that. */
5560     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
5561     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5562
5563     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
5564     for (j=0; j<2; j++) {
5565
5566         /* Inner loop just changes the D3DRS_SHADEMODE */
5567         for (i=0; i<3; i++) {
5568             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5569             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5570
5571             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
5572             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5573
5574             hr = IDirect3DDevice9_BeginScene(device);
5575             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
5576             if(SUCCEEDED(hr))
5577             {
5578                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
5579                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
5580
5581                 hr = IDirect3DDevice9_EndScene(device);
5582                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
5583             }
5584
5585             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5586             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5587
5588             /* Sample two spots from the output */
5589             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
5590             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
5591             switch(shademode) {
5592                 case D3DSHADE_FLAT:
5593                     /* Should take the color of the first vertex of each triangle */
5594                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
5595                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
5596                     shademode = D3DSHADE_GOURAUD;
5597                     break;
5598                 case D3DSHADE_GOURAUD:
5599                     /* Should be an interpolated blend */
5600                     ok(color0 == 0x000dca28, "GOURAUD shading has color0 %08x, expected 0x000dca28\n", color0);
5601                     ok(color1 == 0x000d45c7, "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
5602                     shademode = D3DSHADE_PHONG;
5603                     break;
5604                 case D3DSHADE_PHONG:
5605                     /* Should be the same as GOURAUD, since no hardware implements this */
5606                     ok(color0 == 0x000dca28, "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
5607                     ok(color1 == 0x000d45c7, "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
5608                     break;
5609             }
5610         }
5611         /* Now, do it all over again with a TRIANGLELIST */
5612         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
5613         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5614         primtype = D3DPT_TRIANGLELIST;
5615         shademode = D3DSHADE_FLAT;
5616     }
5617
5618 bail:
5619     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
5620     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5621     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
5622     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5623
5624     if (vb_strip)
5625         IDirect3DVertexBuffer9_Release(vb_strip);
5626     if (vb_list)
5627         IDirect3DVertexBuffer9_Release(vb_list);
5628 }
5629
5630
5631 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
5632 {
5633     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
5634      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
5635      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
5636      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
5637      * 0.73
5638      *
5639      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
5640      * so use shaders for this task
5641      */
5642     IDirect3DPixelShader9 *pshader;
5643     IDirect3DVertexShader9 *vshader;
5644     IDirect3D9 *d3d;
5645     DWORD vshader_code[] = {
5646         0xfffe0101,                                                             /* vs_1_1                       */
5647         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5648         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
5649         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5650         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
5651         0x0000ffff                                                              /* end                          */
5652     };
5653     DWORD pshader_code[] = {
5654         0xffff0101,                                                             /* ps_1_1                       */
5655         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5656         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5657         0x0000ffff                                                              /* end                          */
5658     };
5659     const float quad[] = {
5660        -1.0,   -1.0,    0.1,
5661         1.0,   -1.0,    0.1,
5662        -1.0,    1.0,    0.1,
5663         1.0,    1.0,    0.1
5664     };
5665     HRESULT hr;
5666     DWORD color;
5667
5668     IDirect3DDevice9_GetDirect3D(device, &d3d);
5669     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5670                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
5671                                     D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
5672         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
5673         IDirect3D9_Release(d3d);
5674         return;
5675     }
5676     IDirect3D9_Release(d3d);
5677
5678     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5679     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5680
5681     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5682     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5683     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
5684     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5685     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
5686     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5687     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
5688     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5689     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
5690     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5691
5692     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5693     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5694     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
5695     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5696     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5697     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
5698     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5699     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5700     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
5701     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5702
5703     hr = IDirect3DDevice9_BeginScene(device);
5704     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5705     if(SUCCEEDED(hr)) {
5706         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
5707         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5708
5709         hr = IDirect3DDevice9_EndScene(device);
5710         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5711     }
5712
5713     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5714     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5715     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5716     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5717     IDirect3DPixelShader9_Release(pshader);
5718     IDirect3DVertexShader9_Release(vshader);
5719
5720     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
5721     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5722     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
5723     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5724
5725     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5726     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5727     color = getPixelColor(device, 160, 360);
5728     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
5729        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
5730 }
5731
5732 static void alpha_test(IDirect3DDevice9 *device)
5733 {
5734     HRESULT hr;
5735     IDirect3DTexture9 *offscreenTexture;
5736     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
5737     DWORD color, red, green, blue;
5738
5739     struct vertex quad1[] =
5740     {
5741         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
5742         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
5743         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
5744         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
5745     };
5746     struct vertex quad2[] =
5747     {
5748         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
5749         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
5750         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
5751         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
5752     };
5753     static const float composite_quad[][5] = {
5754         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
5755         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
5756         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
5757         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
5758     };
5759
5760     /* Clear the render target with alpha = 0.5 */
5761     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5762     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5763
5764     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
5765     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
5766
5767     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5768     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
5769     if(!backbuffer) {
5770         goto out;
5771     }
5772
5773     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
5774     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
5775     if(!offscreen) {
5776         goto out;
5777     }
5778
5779     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
5780     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5781
5782     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5783     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5784     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5785     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5786     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
5787     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
5788     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
5789     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
5790     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5791     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5792
5793     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
5794     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5795     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
5796
5797         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
5798          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
5799          * the input alpha
5800          *
5801          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
5802          * They give essentially ZERO and ONE blend factors
5803          */
5804         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5805         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5806         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5807         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5809         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5810
5811         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5812         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5813         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5814         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5815         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5816         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5817
5818         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
5819          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
5820          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
5821          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
5822          * vertices
5823          */
5824         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
5825         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5826         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5827         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5828
5829         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5830         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5831         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5832         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5834         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5835
5836         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5837         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5838         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5839         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5840         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5841         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5842
5843         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
5844         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5845
5846         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
5847          * Disable alpha blending for the final composition
5848          */
5849         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
5850         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5851         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5852         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5853
5854         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
5855         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5856         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
5857         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5858         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5859         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5860
5861         hr = IDirect3DDevice9_EndScene(device);
5862         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
5863     }
5864
5865     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5866
5867     color = getPixelColor(device, 160, 360);
5868     red =   (color & 0x00ff0000) >> 16;
5869     green = (color & 0x0000ff00) >>  8;
5870     blue =  (color & 0x000000ff);
5871     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
5872        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
5873
5874     color = getPixelColor(device, 160, 120);
5875     red =   (color & 0x00ff0000) >> 16;
5876     green = (color & 0x0000ff00) >>  8;
5877     blue =  (color & 0x000000ff);
5878     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
5879        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
5880
5881     color = getPixelColor(device, 480, 360);
5882     red =   (color & 0x00ff0000) >> 16;
5883     green = (color & 0x0000ff00) >>  8;
5884     blue =  (color & 0x000000ff);
5885     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
5886        "SRCALPHA on texture returned color %08x, expected bar\n", color);
5887
5888     color = getPixelColor(device, 480, 120);
5889     red =   (color & 0x00ff0000) >> 16;
5890     green = (color & 0x0000ff00) >>  8;
5891     blue =  (color & 0x000000ff);
5892     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
5893        "DSTALPHA on texture returned color %08x, expected foo\n", color);
5894
5895     out:
5896     /* restore things */
5897     if(backbuffer) {
5898         IDirect3DSurface9_Release(backbuffer);
5899     }
5900     if(offscreenTexture) {
5901         IDirect3DTexture9_Release(offscreenTexture);
5902     }
5903     if(offscreen) {
5904         IDirect3DSurface9_Release(offscreen);
5905     }
5906 }
5907
5908 struct vertex_shortcolor {
5909     float x, y, z;
5910     unsigned short r, g, b, a;
5911 };
5912 struct vertex_floatcolor {
5913     float x, y, z;
5914     float r, g, b, a;
5915 };
5916
5917 static void fixed_function_decl_test(IDirect3DDevice9 *device)
5918 {
5919     HRESULT hr;
5920     BOOL s_ok, ub_ok, f_ok;
5921     DWORD color, size, i;
5922     void *data;
5923     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
5924         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5925         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5926         D3DDECL_END()
5927     };
5928     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
5929         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5930         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5931         D3DDECL_END()
5932     };
5933     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
5934         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5935         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5936         D3DDECL_END()
5937     };
5938     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
5939         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5940         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5941         D3DDECL_END()
5942     };
5943     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
5944         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5945         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5946         D3DDECL_END()
5947     };
5948     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
5949         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5950         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5951         D3DDECL_END()
5952     };
5953     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
5954         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5955         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5956         D3DDECL_END()
5957     };
5958     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
5959     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
5960     IDirect3DVertexBuffer9 *vb, *vb2;
5961     struct vertex quad1[] =                             /* D3DCOLOR */
5962     {
5963         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
5964         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
5965         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
5966         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
5967     };
5968     struct vertex quad2[] =                             /* UBYTE4N */
5969     {
5970         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
5971         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
5972         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
5973         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
5974     };
5975     struct vertex_shortcolor quad3[] =                  /* short */
5976     {
5977         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5978         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5979         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5980         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
5981     };
5982     struct vertex_floatcolor quad4[] =
5983     {
5984         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5985         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5986         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5987         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
5988     };
5989     DWORD colors[] = {
5990         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5991         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5992         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5993         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5994         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5995         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5996         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5997         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5998         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
5999         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6000         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6001         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6002         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6003         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6004         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6005         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6006     };
6007     float quads[] = {
6008         -1.0,   -1.0,     0.1,
6009         -1.0,    0.0,     0.1,
6010          0.0,   -1.0,     0.1,
6011          0.0,    0.0,     0.1,
6012
6013          0.0,   -1.0,     0.1,
6014          0.0,    0.0,     0.1,
6015          1.0,   -1.0,     0.1,
6016          1.0,    0.0,     0.1,
6017
6018          0.0,    0.0,     0.1,
6019          0.0,    1.0,     0.1,
6020          1.0,    0.0,     0.1,
6021          1.0,    1.0,     0.1,
6022
6023         -1.0,    0.0,     0.1,
6024         -1.0,    1.0,     0.1,
6025          0.0,    0.0,     0.1,
6026          0.0,    1.0,     0.1
6027     };
6028     struct tvertex quad_transformed[] = {
6029        {  90,    110,     0.1,      2.0,        0x00ffff00},
6030        { 570,    110,     0.1,      2.0,        0x00ffff00},
6031        {  90,    300,     0.1,      2.0,        0x00ffff00},
6032        { 570,    300,     0.1,      2.0,        0x00ffff00}
6033     };
6034     D3DCAPS9 caps;
6035
6036     memset(&caps, 0, sizeof(caps));
6037     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6038     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6039
6040     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6041     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6042
6043     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6044     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6045     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6046     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6047     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6048     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6049     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6050         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6051         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6052         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6053         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6054     } else {
6055         trace("D3DDTCAPS_UBYTE4N not supported\n");
6056         dcl_ubyte_2 = NULL;
6057         dcl_ubyte = NULL;
6058     }
6059     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6060     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6061     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6062     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6063
6064     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6065     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6066                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6067     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6068
6069     hr = IDirect3DDevice9_BeginScene(device);
6070     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6071     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6072     if(SUCCEEDED(hr)) {
6073         if(dcl_color) {
6074             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6075             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6076             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6077             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6078         }
6079
6080         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6081          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6082          * using software vertex processing. Doh!
6083          */
6084         if(dcl_ubyte) {
6085             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6086             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6087             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6088             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6089             ub_ok = SUCCEEDED(hr);
6090         }
6091
6092         if(dcl_short) {
6093             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6094             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6095             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6096             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6097             s_ok = SUCCEEDED(hr);
6098         }
6099
6100         if(dcl_float) {
6101             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6102             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6103             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6104             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6105             f_ok = SUCCEEDED(hr);
6106         }
6107
6108         hr = IDirect3DDevice9_EndScene(device);
6109         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6110     }
6111
6112     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6113     if(dcl_short) {
6114         color = getPixelColor(device, 480, 360);
6115         ok(color == 0x000000ff || !s_ok,
6116            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6117     }
6118     if(dcl_ubyte) {
6119         color = getPixelColor(device, 160, 120);
6120         ok(color == 0x0000ffff || !ub_ok,
6121            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6122     }
6123     if(dcl_color) {
6124         color = getPixelColor(device, 160, 360);
6125         ok(color == 0x00ffff00,
6126            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6127     }
6128     if(dcl_float) {
6129         color = getPixelColor(device, 480, 120);
6130         ok(color == 0x00ff0000 || !f_ok,
6131            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
6132     }
6133
6134     /* The following test with vertex buffers doesn't serve to find out new information from windows.
6135      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
6136      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
6137      * whether the immediate mode code works
6138      */
6139     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6140     hr = IDirect3DDevice9_BeginScene(device);
6141     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6142     if(SUCCEEDED(hr)) {
6143         if(dcl_color) {
6144             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
6145             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6146             memcpy(data, quad1, sizeof(quad1));
6147             hr = IDirect3DVertexBuffer9_Unlock(vb);
6148             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6149             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6150             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6151             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
6152             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6153             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6154             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6155         }
6156
6157         if(dcl_ubyte) {
6158             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
6159             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6160             memcpy(data, quad2, sizeof(quad2));
6161             hr = IDirect3DVertexBuffer9_Unlock(vb);
6162             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6163             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6164             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6165             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
6166             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6167             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6168             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6169                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6170             ub_ok = SUCCEEDED(hr);
6171         }
6172
6173         if(dcl_short) {
6174             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
6175             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6176             memcpy(data, quad3, sizeof(quad3));
6177             hr = IDirect3DVertexBuffer9_Unlock(vb);
6178             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6179             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6180             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6181             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
6182             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6183             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6184             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6185                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6186             s_ok = SUCCEEDED(hr);
6187         }
6188
6189         if(dcl_float) {
6190             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
6191             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6192             memcpy(data, quad4, sizeof(quad4));
6193             hr = IDirect3DVertexBuffer9_Unlock(vb);
6194             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6195             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6196             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6197             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
6198             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6199             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6200             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6201                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6202             f_ok = SUCCEEDED(hr);
6203         }
6204
6205         hr = IDirect3DDevice9_EndScene(device);
6206         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6207     }
6208
6209     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6210     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6211     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6212     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6213
6214     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6215     if(dcl_short) {
6216         color = getPixelColor(device, 480, 360);
6217         ok(color == 0x000000ff || !s_ok,
6218            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6219     }
6220     if(dcl_ubyte) {
6221         color = getPixelColor(device, 160, 120);
6222         ok(color == 0x0000ffff || !ub_ok,
6223            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6224     }
6225     if(dcl_color) {
6226         color = getPixelColor(device, 160, 360);
6227         ok(color == 0x00ffff00,
6228            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6229     }
6230     if(dcl_float) {
6231         color = getPixelColor(device, 480, 120);
6232         ok(color == 0x00ff0000 || !f_ok,
6233            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
6234     }
6235
6236     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6237     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
6238
6239     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
6240     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6241     memcpy(data, quad_transformed, sizeof(quad_transformed));
6242     hr = IDirect3DVertexBuffer9_Unlock(vb);
6243     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6244
6245     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
6246     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6247
6248     hr = IDirect3DDevice9_BeginScene(device);
6249     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6250     if(SUCCEEDED(hr)) {
6251         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
6252         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6253         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6254         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6255
6256         hr = IDirect3DDevice9_EndScene(device);
6257         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6258     }
6259
6260     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6261     color = getPixelColor(device, 88, 108);
6262     ok(color == 0x000000ff,
6263        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
6264     color = getPixelColor(device, 92, 108);
6265     ok(color == 0x000000ff,
6266        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
6267     color = getPixelColor(device, 88, 112);
6268     ok(color == 0x000000ff,
6269        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
6270     color = getPixelColor(device, 92, 112);
6271     ok(color == 0x00ffff00,
6272        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
6273
6274     color = getPixelColor(device, 568, 108);
6275     ok(color == 0x000000ff,
6276        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
6277     color = getPixelColor(device, 572, 108);
6278     ok(color == 0x000000ff,
6279        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
6280     color = getPixelColor(device, 568, 112);
6281     ok(color == 0x00ffff00,
6282        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
6283     color = getPixelColor(device, 572, 112);
6284     ok(color == 0x000000ff,
6285        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
6286
6287     color = getPixelColor(device, 88, 298);
6288     ok(color == 0x000000ff,
6289        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
6290     color = getPixelColor(device, 92, 298);
6291     ok(color == 0x00ffff00,
6292        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
6293     color = getPixelColor(device, 88, 302);
6294     ok(color == 0x000000ff,
6295        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
6296     color = getPixelColor(device, 92, 302);
6297     ok(color == 0x000000ff,
6298        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
6299
6300     color = getPixelColor(device, 568, 298);
6301     ok(color == 0x00ffff00,
6302        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
6303     color = getPixelColor(device, 572, 298);
6304     ok(color == 0x000000ff,
6305        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
6306     color = getPixelColor(device, 568, 302);
6307     ok(color == 0x000000ff,
6308        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
6309     color = getPixelColor(device, 572, 302);
6310     ok(color == 0x000000ff,
6311        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
6312
6313     /* This test is pointless without those two declarations: */
6314     if((!dcl_color_2) || (!dcl_ubyte_2)) {
6315         skip("color-ubyte switching test declarations aren't supported\n");
6316         goto out;
6317     }
6318
6319     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
6320     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6321     memcpy(data, quads, sizeof(quads));
6322     hr = IDirect3DVertexBuffer9_Unlock(vb);
6323     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6324     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
6325                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
6326     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6327     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
6328     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6329     memcpy(data, colors, sizeof(colors));
6330     hr = IDirect3DVertexBuffer9_Unlock(vb2);
6331     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
6332
6333     for(i = 0; i < 2; i++) {
6334         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6335         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
6336
6337         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
6338         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6339         if(i == 0) {
6340             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
6341         } else {
6342             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
6343         }
6344         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6345
6346         hr = IDirect3DDevice9_BeginScene(device);
6347         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6348         ub_ok = FALSE;
6349         if(SUCCEEDED(hr)) {
6350             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
6351             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6352             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6353             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6354                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6355             ub_ok = SUCCEEDED(hr);
6356
6357             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
6358             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6359             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
6360             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6361
6362             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
6363             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6364             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
6365             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6366                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6367             ub_ok = (SUCCEEDED(hr) && ub_ok);
6368
6369             hr = IDirect3DDevice9_EndScene(device);
6370             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6371         }
6372
6373         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6374         if(i == 0) {
6375             color = getPixelColor(device, 480, 360);
6376             ok(color == 0x00ff0000,
6377                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
6378             color = getPixelColor(device, 160, 120);
6379             ok(color == 0x00ffffff,
6380                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6381             color = getPixelColor(device, 160, 360);
6382             ok(color == 0x000000ff || !ub_ok,
6383                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6384             color = getPixelColor(device, 480, 120);
6385             ok(color == 0x000000ff || !ub_ok,
6386                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6387         } else {
6388             color = getPixelColor(device, 480, 360);
6389             ok(color == 0x000000ff,
6390                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
6391             color = getPixelColor(device, 160, 120);
6392             ok(color == 0x00ffffff,
6393                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6394             color = getPixelColor(device, 160, 360);
6395             ok(color == 0x00ff0000 || !ub_ok,
6396                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6397             color = getPixelColor(device, 480, 120);
6398             ok(color == 0x00ff0000 || !ub_ok,
6399                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6400         }
6401     }
6402
6403     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6404     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6405     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
6406     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6407     IDirect3DVertexBuffer9_Release(vb2);
6408
6409     out:
6410     IDirect3DVertexBuffer9_Release(vb);
6411     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
6412     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
6413     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
6414     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
6415     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
6416     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
6417     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
6418 }
6419
6420 struct vertex_float16color {
6421     float x, y, z;
6422     DWORD c1, c2;
6423 };
6424
6425 static void test_vshader_float16(IDirect3DDevice9 *device)
6426 {
6427     HRESULT hr;
6428     DWORD color;
6429     void *data;
6430     static const D3DVERTEXELEMENT9 decl_elements[] = {
6431         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6432         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6433         D3DDECL_END()
6434     };
6435     IDirect3DVertexDeclaration9 *vdecl = NULL;
6436     IDirect3DVertexBuffer9 *buffer = NULL;
6437     IDirect3DVertexShader9 *shader;
6438     DWORD shader_code[] = {
6439         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
6440         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
6441         0x90e40001, 0x0000ffff
6442     };
6443     struct vertex_float16color quad[] = {
6444         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
6445         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
6446         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
6447         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
6448
6449         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
6450         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
6451         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
6452         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
6453
6454         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
6455         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
6456         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
6457         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
6458
6459         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
6460         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
6461         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
6462         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
6463     };
6464
6465     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6466     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6467
6468     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
6469     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
6470     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
6471     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6472     IDirect3DDevice9_SetVertexShader(device, shader);
6473     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6474
6475     hr = IDirect3DDevice9_BeginScene(device);
6476     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6477     if(SUCCEEDED(hr)) {
6478         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
6479         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6480         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
6481         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6482         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
6483         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6484         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
6485         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6486         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
6487         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6488
6489         hr = IDirect3DDevice9_EndScene(device);
6490         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6491     }
6492     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6493     color = getPixelColor(device, 480, 360);
6494     ok(color == 0x00ff0000,
6495        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6496     color = getPixelColor(device, 160, 120);
6497     ok(color == 0x00000000,
6498        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6499     color = getPixelColor(device, 160, 360);
6500     ok(color == 0x0000ff00,
6501        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6502     color = getPixelColor(device, 480, 120);
6503     ok(color == 0x000000ff,
6504        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6505
6506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6508
6509     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
6510                                              D3DPOOL_MANAGED, &buffer, NULL);
6511     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
6512     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
6513     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
6514     memcpy(data, quad, sizeof(quad));
6515     hr = IDirect3DVertexBuffer9_Unlock(buffer);
6516     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
6517     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
6518     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6519
6520     hr = IDirect3DDevice9_BeginScene(device);
6521     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6522     if(SUCCEEDED(hr)) {
6523             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
6524             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6525             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
6526             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6527             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
6528             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6529             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
6530             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6531
6532             hr = IDirect3DDevice9_EndScene(device);
6533             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6534     }
6535
6536     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6537     color = getPixelColor(device, 480, 360);
6538     ok(color == 0x00ff0000,
6539        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6540     color = getPixelColor(device, 160, 120);
6541     ok(color == 0x00000000,
6542        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6543     color = getPixelColor(device, 160, 360);
6544     ok(color == 0x0000ff00,
6545        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6546     color = getPixelColor(device, 480, 120);
6547     ok(color == 0x000000ff,
6548        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6549
6550     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6551     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6552     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6553     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6554     IDirect3DDevice9_SetVertexShader(device, NULL);
6555     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6556
6557     IDirect3DVertexDeclaration9_Release(vdecl);
6558     IDirect3DVertexShader9_Release(shader);
6559     IDirect3DVertexBuffer9_Release(buffer);
6560 }
6561
6562 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
6563 {
6564     D3DCAPS9 caps;
6565     IDirect3DTexture9 *texture;
6566     HRESULT hr;
6567     D3DLOCKED_RECT rect;
6568     unsigned int x, y;
6569     DWORD *dst, color;
6570     const float quad[] = {
6571         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
6572          1.0,   -1.0,   0.1,    1.2,   -0.2,
6573         -1.0,    1.0,   0.1,   -0.2,    1.2,
6574          1.0,    1.0,   0.1,    1.2,    1.2
6575     };
6576     memset(&caps, 0, sizeof(caps));
6577
6578     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6579     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6580     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6581         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
6582         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
6583            "Card has conditional NP2 support without power of two restriction set\n");
6584         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
6585         return;
6586     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6587         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
6588         return;
6589     }
6590
6591     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
6592     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6593
6594     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6595     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6596
6597     memset(&rect, 0, sizeof(rect));
6598     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
6599     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
6600     for(y = 0; y < 10; y++) {
6601         for(x = 0; x < 10; x++) {
6602             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
6603             if(x == 0 || x == 9 || y == 0 || y == 9) {
6604                 *dst = 0x00ff0000;
6605             } else {
6606                 *dst = 0x000000ff;
6607             }
6608         }
6609     }
6610     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6611     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
6612
6613     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6614     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6615     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
6616     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6617     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
6618     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6619     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6620     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6621
6622     hr = IDirect3DDevice9_BeginScene(device);
6623     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6624     if(SUCCEEDED(hr)) {
6625         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
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
6632     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6633
6634     color = getPixelColor(device,    1,  1);
6635     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
6636     color = getPixelColor(device, 639, 479);
6637     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
6638
6639     color = getPixelColor(device, 135, 101);
6640     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
6641     color = getPixelColor(device, 140, 101);
6642     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
6643     color = getPixelColor(device, 135, 105);
6644     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
6645     color = getPixelColor(device, 140, 105);
6646     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
6647
6648     color = getPixelColor(device, 135, 376);
6649     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
6650     color = getPixelColor(device, 140, 376);
6651     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
6652     color = getPixelColor(device, 135, 379);
6653     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
6654     color = getPixelColor(device, 140, 379);
6655     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
6656
6657     color = getPixelColor(device, 500, 101);
6658     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
6659     color = getPixelColor(device, 504, 101);
6660     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
6661     color = getPixelColor(device, 500, 105);
6662     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
6663     color = getPixelColor(device, 504, 105);
6664     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
6665
6666     color = getPixelColor(device, 500, 376);
6667     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
6668     color = getPixelColor(device, 504, 376);
6669     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
6670     color = getPixelColor(device, 500, 380);
6671     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
6672     color = getPixelColor(device, 504, 380);
6673     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
6674
6675     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6676     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6677     IDirect3DTexture9_Release(texture);
6678 }
6679
6680 static void vFace_register_test(IDirect3DDevice9 *device)
6681 {
6682     HRESULT hr;
6683     DWORD color;
6684     const DWORD shader_code[] = {
6685         0xffff0300,                                                             /* ps_3_0                     */
6686         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
6687         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
6688         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
6689         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
6690         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
6691         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
6692         0x0000ffff                                                              /* END                        */
6693     };
6694     IDirect3DPixelShader9 *shader;
6695     IDirect3DTexture9 *texture;
6696     IDirect3DSurface9 *surface, *backbuffer;
6697     const float quad[] = {
6698         -1.0,   -1.0,   0.1,
6699          1.0,   -1.0,   0.1,
6700         -1.0,    0.0,   0.1,
6701
6702          1.0,   -1.0,   0.1,
6703          1.0,    0.0,   0.1,
6704         -1.0,    0.0,   0.1,
6705
6706         -1.0,    0.0,   0.1,
6707         -1.0,    1.0,   0.1,
6708          1.0,    0.0,   0.1,
6709
6710          1.0,    0.0,   0.1,
6711         -1.0,    1.0,   0.1,
6712          1.0,    1.0,   0.1,
6713     };
6714     const float blit[] = {
6715          0.0,   -1.0,   0.1,    0.0,    0.0,
6716          1.0,   -1.0,   0.1,    1.0,    0.0,
6717          0.0,    1.0,   0.1,    0.0,    1.0,
6718          1.0,    1.0,   0.1,    1.0,    1.0,
6719     };
6720
6721     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6722     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
6723     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6724     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6725     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6726     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
6727     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6728     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6729     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6730     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6731     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6732     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
6733
6734     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6735     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6736
6737     hr = IDirect3DDevice9_BeginScene(device);
6738     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6739     if(SUCCEEDED(hr)) {
6740         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
6741         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6742         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6743         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6744         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6745         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6746         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6747         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6748         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6749         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6750         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6751
6752         /* Blit the texture ontp the back buffer to make it visible */
6753         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6754         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
6755         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6756         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
6757         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6758         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6759         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6760         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6761         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6762         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6763
6764         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, 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     color = getPixelColor(device, 160, 360);
6773     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6774     color = getPixelColor(device, 160, 120);
6775     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6776     color = getPixelColor(device, 480, 360);
6777     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6778     color = getPixelColor(device, 480, 120);
6779     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6780
6781     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6782     IDirect3DDevice9_SetTexture(device, 0, NULL);
6783     IDirect3DPixelShader9_Release(shader);
6784     IDirect3DSurface9_Release(surface);
6785     IDirect3DSurface9_Release(backbuffer);
6786     IDirect3DTexture9_Release(texture);
6787 }
6788
6789 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
6790 {
6791     HRESULT hr;
6792     DWORD color;
6793     int i;
6794     D3DCAPS9 caps;
6795
6796     static const float quad[][7] = {
6797         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
6798         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
6799         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
6800         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
6801     };
6802
6803     static const D3DVERTEXELEMENT9 decl_elements[] = {
6804         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6805         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6806         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6807         D3DDECL_END()
6808     };
6809
6810     /* use assymetric matrix to test loading */
6811     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
6812
6813     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
6814     IDirect3DTexture9           *texture            = NULL;
6815
6816     memset(&caps, 0, sizeof(caps));
6817     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6818     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6819     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
6820         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
6821         return;
6822     } else {
6823         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
6824          * They report that it is not supported, but after that bump mapping works properly. So just test
6825          * if the format is generally supported, and check the BUMPENVMAP flag
6826          */
6827         IDirect3D9 *d3d9;
6828
6829         IDirect3DDevice9_GetDirect3D(device, &d3d9);
6830         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
6831                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
6832         IDirect3D9_Release(d3d9);
6833         if(FAILED(hr)) {
6834             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
6835             return;
6836         }
6837     }
6838
6839     /* Generate the textures */
6840     generate_bumpmap_textures(device);
6841
6842     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
6843     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6844     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
6845     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6846     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
6847     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6848     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
6849     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6850
6851     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
6852     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6853     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
6854     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6855     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
6856     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6857
6858     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6859     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6860     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6861     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6862     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
6863     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6864
6865     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
6866     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6867
6868     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6869     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
6870
6871     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
6872     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
6873
6874
6875     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
6876     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
6877     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
6878     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
6879
6880     hr = IDirect3DDevice9_BeginScene(device);
6881     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
6882
6883     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
6884     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
6885
6886     hr = IDirect3DDevice9_EndScene(device);
6887     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
6888
6889     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6890     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
6891
6892     color = getPixelColor(device, 320-32, 240);
6893     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6894     color = getPixelColor(device, 320+32, 240);
6895     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6896     color = getPixelColor(device, 320, 240-32);
6897     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6898     color = getPixelColor(device, 320, 240+32);
6899     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6900     color = getPixelColor(device, 320, 240);
6901     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6902     color = getPixelColor(device, 320+32, 240+32);
6903     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6904     color = getPixelColor(device, 320-32, 240+32);
6905     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6906     color = getPixelColor(device, 320+32, 240-32);
6907     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6908     color = getPixelColor(device, 320-32, 240-32);
6909     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6910
6911     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6912     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
6913     IDirect3DVertexDeclaration9_Release(vertex_declaration);
6914
6915     for(i = 0; i < 2; i++) {
6916         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
6917         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
6918         IDirect3DTexture9_Release(texture); /* For the GetTexture */
6919         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
6920         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
6921         IDirect3DTexture9_Release(texture); /* To destroy it */
6922     }
6923
6924     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6925     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6926     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
6927     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6928
6929 }
6930
6931 static void stencil_cull_test(IDirect3DDevice9 *device) {
6932     HRESULT hr;
6933     IDirect3DSurface9 *depthstencil = NULL;
6934     D3DSURFACE_DESC desc;
6935     float quad1[] = {
6936         -1.0,   -1.0,   0.1,
6937          0.0,   -1.0,   0.1,
6938         -1.0,    0.0,   0.1,
6939          0.0,    0.0,   0.1,
6940     };
6941     float quad2[] = {
6942          0.0,   -1.0,   0.1,
6943          1.0,   -1.0,   0.1,
6944          0.0,    0.0,   0.1,
6945          1.0,    0.0,   0.1,
6946     };
6947     float quad3[] = {
6948         0.0,    0.0,   0.1,
6949         1.0,    0.0,   0.1,
6950         0.0,    1.0,   0.1,
6951         1.0,    1.0,   0.1,
6952     };
6953     float quad4[] = {
6954         -1.0,    0.0,   0.1,
6955          0.0,    0.0,   0.1,
6956         -1.0,    1.0,   0.1,
6957          0.0,    1.0,   0.1,
6958     };
6959     struct vertex painter[] = {
6960        {-1.0,   -1.0,   0.0,    0x00000000},
6961        { 1.0,   -1.0,   0.0,    0x00000000},
6962        {-1.0,    1.0,   0.0,    0x00000000},
6963        { 1.0,    1.0,   0.0,    0x00000000},
6964     };
6965     WORD indices_cw[]  = {0, 1, 3};
6966     WORD indices_ccw[] = {0, 2, 3};
6967     unsigned int i;
6968     DWORD color;
6969
6970     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
6971     if(depthstencil == NULL) {
6972         skip("No depth stencil buffer\n");
6973         return;
6974     }
6975     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
6976     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
6977     IDirect3DSurface9_Release(depthstencil);
6978     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
6979         skip("No 4 or 8 bit stencil surface\n");
6980         return;
6981     }
6982
6983     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
6984     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6985     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6986
6987     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
6988     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6989     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
6990     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6991     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
6992     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
6994     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6995
6996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
6997     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6998     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
6999     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7000     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7001     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7002
7003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7004     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7006     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7007
7008     /* First pass: Fill the stencil buffer with some values... */
7009     hr = IDirect3DDevice9_BeginScene(device);
7010     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7011     if(SUCCEEDED(hr))
7012     {
7013         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7014         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7015         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7016                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7017         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7018                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7019
7020         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7021         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7022         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7023         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7024         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7025                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7026         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7027                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7028
7029         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7030         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7031         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7032                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7033         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7034                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7035
7036         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7037         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7038         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7039                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7040         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7041                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7042
7043         hr = IDirect3DDevice9_EndScene(device);
7044         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7045     }
7046
7047     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7048     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7049     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7051     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7053     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7055     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7059     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7060
7061     /* 2nd pass: Make the stencil values visible */
7062     hr = IDirect3DDevice9_BeginScene(device);
7063     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7064     if(SUCCEEDED(hr))
7065     {
7066         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7067         for(i = 0; i < 16; i++) {
7068             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7069             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7070
7071             painter[0].diffuse = (i * 16); /* Creates shades of blue */
7072             painter[1].diffuse = (i * 16);
7073             painter[2].diffuse = (i * 16);
7074             painter[3].diffuse = (i * 16);
7075             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7076             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7077         }
7078         hr = IDirect3DDevice9_EndScene(device);
7079         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7080     }
7081
7082     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7083     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7084
7085     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7086     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7087
7088     color = getPixelColor(device, 160, 420);
7089     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7090     color = getPixelColor(device, 160, 300);
7091     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7092
7093     color = getPixelColor(device, 480, 420);
7094     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7095     color = getPixelColor(device, 480, 300);
7096     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
7097
7098     color = getPixelColor(device, 160, 180);
7099     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
7100     color = getPixelColor(device, 160, 60);
7101     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
7102
7103     color = getPixelColor(device, 480, 180);
7104     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
7105     color = getPixelColor(device, 480, 60);
7106     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7107 }
7108
7109 static void vpos_register_test(IDirect3DDevice9 *device)
7110 {
7111     HRESULT hr;
7112     DWORD color;
7113     const DWORD shader_code[] = {
7114     0xffff0300,                                                             /* ps_3_0                     */
7115     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
7116     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
7117     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
7118     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
7119     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
7120     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
7121     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
7122     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
7123     0x0000ffff                                                              /* end                        */
7124     };
7125     const DWORD shader_frac_code[] = {
7126     0xffff0300,                                                             /* ps_3_0                     */
7127     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
7128     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
7129     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
7130     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
7131     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7132     0x0000ffff                                                              /* end                        */
7133     };
7134     IDirect3DPixelShader9 *shader, *shader_frac;
7135     IDirect3DSurface9 *surface = NULL, *backbuffer;
7136     const float quad[] = {
7137         -1.0,   -1.0,   0.1,    0.0,    0.0,
7138          1.0,   -1.0,   0.1,    1.0,    0.0,
7139         -1.0,    1.0,   0.1,    0.0,    1.0,
7140          1.0,    1.0,   0.1,    1.0,    1.0,
7141     };
7142     D3DLOCKED_RECT lr;
7143     float constant[4] = {1.0, 0.0, 320, 240};
7144     DWORD *pos;
7145
7146     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7147     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7148     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7149     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7150     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
7151     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7152     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7153     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7154     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7155     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7156     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7157     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7158
7159     hr = IDirect3DDevice9_BeginScene(device);
7160     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7161     if(SUCCEEDED(hr)) {
7162         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
7163         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
7164         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7165         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7166         hr = IDirect3DDevice9_EndScene(device);
7167         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7168     }
7169
7170     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7171     /* This has to be pixel exact */
7172     color = getPixelColor(device, 319, 239);
7173     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
7174     color = getPixelColor(device, 320, 239);
7175     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
7176     color = getPixelColor(device, 319, 240);
7177     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
7178     color = getPixelColor(device, 320, 240);
7179     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
7180
7181     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
7182                                              &surface, NULL);
7183     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
7184     hr = IDirect3DDevice9_BeginScene(device);
7185     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7186     if(SUCCEEDED(hr)) {
7187         constant[2] = 16; constant[3] = 16;
7188         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
7189         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
7190         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7191         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7192         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7193         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7194         hr = IDirect3DDevice9_EndScene(device);
7195         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7196     }
7197     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
7198     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
7199
7200     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
7201     color = *pos & 0x00ffffff;
7202     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
7203     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
7204     color = *pos & 0x00ffffff;
7205     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
7206     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
7207     color = *pos & 0x00ffffff;
7208     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
7209     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
7210     color = *pos & 0x00ffffff;
7211     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
7212
7213     hr = IDirect3DSurface9_UnlockRect(surface);
7214     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
7215
7216     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
7217      * have full control over the multisampling setting inside this test
7218      */
7219     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
7220     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7221     hr = IDirect3DDevice9_BeginScene(device);
7222     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7223     if(SUCCEEDED(hr)) {
7224         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7225         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7226         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7227         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7228         hr = IDirect3DDevice9_EndScene(device);
7229         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7230     }
7231     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7232     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7233
7234     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
7235     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
7236
7237     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
7238     color = *pos & 0x00ffffff;
7239     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
7240
7241     hr = IDirect3DSurface9_UnlockRect(surface);
7242     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
7243
7244     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7245     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7246     IDirect3DPixelShader9_Release(shader);
7247     IDirect3DPixelShader9_Release(shader_frac);
7248     if(surface) IDirect3DSurface9_Release(surface);
7249     IDirect3DSurface9_Release(backbuffer);
7250 }
7251
7252 static void pointsize_test(IDirect3DDevice9 *device)
7253 {
7254     HRESULT hr;
7255     D3DCAPS9 caps;
7256     D3DMATRIX matrix;
7257     D3DMATRIX identity;
7258     float ptsize, ptsize_orig;
7259     DWORD color;
7260
7261     const float vertices[] = {
7262         64,     64,     0.1,
7263         128,    64,     0.1,
7264         192,    64,     0.1,
7265         256,    64,     0.1,
7266         320,    64,     0.1,
7267         384,    64,     0.1
7268     };
7269
7270     /* 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 */
7271     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;
7272     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;
7273     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;
7274     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;
7275
7276     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;
7277     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;
7278     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;
7279     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;
7280
7281     memset(&caps, 0, sizeof(caps));
7282     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7283     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7284     if(caps.MaxPointSize < 32.0) {
7285         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
7286         return;
7287     }
7288
7289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
7290     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7291     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
7292     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform 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_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
7296     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState 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         ptsize = 16.0;
7302         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7303         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7304         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7305         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7306
7307         ptsize = 32.0;
7308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7310         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
7311         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7312
7313         ptsize = 31.5;
7314         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7315         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
7317         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7318
7319         if(caps.MaxPointSize >= 64.0) {
7320             ptsize = 64.0;
7321             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7322             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7323             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
7324             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7325
7326             ptsize = 63.75;
7327             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7328             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7329             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
7330             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7331         }
7332
7333         ptsize = 1.0;
7334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
7335         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
7336         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
7337         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7338
7339         hr = IDirect3DDevice9_EndScene(device);
7340         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7341     }
7342     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7343     color = getPixelColor(device, 64-9, 64-9);
7344     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
7345     color = getPixelColor(device, 64-8, 64-8);
7346     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
7347     color = getPixelColor(device, 64-7, 64-7);
7348     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
7349     color = getPixelColor(device, 64+7, 64+7);
7350     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
7351     color = getPixelColor(device, 64+8, 64+8);
7352     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
7353     color = getPixelColor(device, 64+9, 64+9);
7354     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
7355
7356     color = getPixelColor(device, 128-17, 64-17);
7357     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
7358     color = getPixelColor(device, 128-16, 64-16);
7359     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
7360     color = getPixelColor(device, 128-15, 64-15);
7361     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
7362     color = getPixelColor(device, 128+15, 64+15);
7363     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
7364     color = getPixelColor(device, 128+16, 64+16);
7365     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
7366     color = getPixelColor(device, 128+17, 64+17);
7367     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
7368
7369     color = getPixelColor(device, 192-17, 64-17);
7370     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
7371     color = getPixelColor(device, 192-16, 64-16);
7372     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
7373     color = getPixelColor(device, 192-15, 64-15);
7374     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
7375     color = getPixelColor(device, 192+15, 64+15);
7376     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
7377     color = getPixelColor(device, 192+16, 64+16);
7378     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
7379     color = getPixelColor(device, 192+17, 64+17);
7380     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
7381
7382     if(caps.MaxPointSize >= 64.0) {
7383         color = getPixelColor(device, 256-33, 64-33);
7384         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
7385         color = getPixelColor(device, 256-32, 64-32);
7386         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
7387         color = getPixelColor(device, 256-31, 64-31);
7388         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
7389         color = getPixelColor(device, 256+31, 64+31);
7390         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
7391         color = getPixelColor(device, 256+32, 64+32);
7392         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
7393         color = getPixelColor(device, 256+33, 64+33);
7394         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
7395
7396         color = getPixelColor(device, 384-33, 64-33);
7397         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
7398         color = getPixelColor(device, 384-32, 64-32);
7399         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
7400         color = getPixelColor(device, 384-31, 64-31);
7401         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
7402         color = getPixelColor(device, 384+31, 64+31);
7403         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
7404         color = getPixelColor(device, 384+32, 64+32);
7405         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
7406         color = getPixelColor(device, 384+33, 64+33);
7407         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
7408     }
7409
7410     color = getPixelColor(device, 320-1, 64-1);
7411     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
7412     color = getPixelColor(device, 320-0, 64-0);
7413     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
7414     color = getPixelColor(device, 320+1, 64+1);
7415     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
7416
7417     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
7418     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
7419     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
7420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
7421 }
7422
7423 START_TEST(visual)
7424 {
7425     IDirect3DDevice9 *device_ptr;
7426     D3DCAPS9 caps;
7427     HRESULT hr;
7428     DWORD color;
7429
7430     d3d9_handle = LoadLibraryA("d3d9.dll");
7431     if (!d3d9_handle)
7432     {
7433         skip("Could not load d3d9.dll\n");
7434         return;
7435     }
7436
7437     device_ptr = init_d3d9();
7438     if (!device_ptr)
7439     {
7440         skip("Creating the device failed\n");
7441         return;
7442     }
7443
7444     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
7445
7446     /* Check for the reliability of the returned data */
7447     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
7448     if(FAILED(hr))
7449     {
7450         trace("Clear failed, can't assure correctness of the test results, skipping\n");
7451         goto cleanup;
7452     }
7453     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
7454
7455     color = getPixelColor(device_ptr, 1, 1);
7456     if(color !=0x00ff0000)
7457     {
7458         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
7459         goto cleanup;
7460     }
7461
7462     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
7463     if(FAILED(hr))
7464     {
7465         trace("Clear failed, can't assure correctness of the test results, skipping\n");
7466         goto cleanup;
7467     }
7468     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
7469
7470     color = getPixelColor(device_ptr, 639, 479);
7471     if(color != 0x0000ddee)
7472     {
7473         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
7474         goto cleanup;
7475     }
7476
7477     /* Now execute the real tests */
7478     lighting_test(device_ptr);
7479     clear_test(device_ptr);
7480     fog_test(device_ptr);
7481     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
7482     {
7483         test_cube_wrap(device_ptr);
7484     } else {
7485         skip("No cube texture support\n");
7486     }
7487     z_range_test(device_ptr);
7488     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
7489     {
7490         maxmip_test(device_ptr);
7491     }
7492     else
7493     {
7494         skip("No mipmap support\n");
7495     }
7496     offscreen_test(device_ptr);
7497     alpha_test(device_ptr);
7498     shademode_test(device_ptr);
7499     srgbtexture_test(device_ptr);
7500     release_buffer_test(device_ptr);
7501     float_texture_test(device_ptr);
7502     g16r16_texture_test(device_ptr);
7503     texture_transform_flags_test(device_ptr);
7504     autogen_mipmap_test(device_ptr);
7505     fixed_function_decl_test(device_ptr);
7506     conditional_np2_repeat_test(device_ptr);
7507     fixed_function_bumpmap_test(device_ptr);
7508     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
7509         stencil_cull_test(device_ptr);
7510     } else {
7511         skip("No two sided stencil support\n");
7512     }
7513     pointsize_test(device_ptr);
7514
7515     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
7516     {
7517         test_constant_clamp_vs(device_ptr);
7518         test_compare_instructions(device_ptr);
7519     }
7520     else skip("No vs_1_1 support\n");
7521
7522     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
7523     {
7524         test_mova(device_ptr);
7525         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
7526             test_vshader_input(device_ptr);
7527             test_vshader_float16(device_ptr);
7528         } else {
7529             skip("No vs_3_0 support\n");
7530         }
7531     }
7532     else skip("No vs_2_0 support\n");
7533
7534     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
7535     {
7536         fog_with_shader_test(device_ptr);
7537         fog_srgbwrite_test(device_ptr);
7538     }
7539     else skip("No vs_1_1 and ps_1_1 support\n");
7540
7541     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
7542     {
7543         texbem_test(device_ptr);
7544         texdepth_test(device_ptr);
7545         texkill_test(device_ptr);
7546         x8l8v8u8_test(device_ptr);
7547         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
7548             constant_clamp_ps_test(device_ptr);
7549             cnd_test(device_ptr);
7550             if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
7551                 nested_loop_test(device_ptr);
7552                 fixed_function_varying_test(device_ptr);
7553                 vFace_register_test(device_ptr);
7554                 vpos_register_test(device_ptr);
7555                 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
7556                     vshader_version_varying_test(device_ptr);
7557                     pshader_version_varying_test(device_ptr);
7558                 } else {
7559                     skip("No vs_3_0 support\n");
7560                 }
7561             } else {
7562                 skip("No ps_3_0 support\n");
7563             }
7564         }
7565     }
7566     else skip("No ps_1_1 support\n");
7567
7568 cleanup:
7569     if(device_ptr) {
7570         ULONG ref;
7571
7572         D3DPRESENT_PARAMETERS present_parameters;
7573         IDirect3DSwapChain9 *swapchain;
7574         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
7575         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
7576         IDirect3DSwapChain9_Release(swapchain);
7577         ref = IDirect3DDevice9_Release(device_ptr);
7578         DestroyWindow(present_parameters.hDeviceWindow);
7579         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
7580     }
7581 }