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