d3d9: Make the shading test even more precision tolerant.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007 Henri Verbeet
3  * Copyright (C) 2007-2008 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 /* Locks a given surface and returns the color at (x,y).  It's the caller's
52  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
53 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
54 {
55     DWORD color;
56     HRESULT hr;
57     D3DSURFACE_DESC desc;
58     RECT rectToLock = {x, y, x+1, y+1};
59     D3DLOCKED_RECT lockedRect;
60
61     hr = IDirect3DSurface9_GetDesc(surface, &desc);
62     if(FAILED(hr))  /* This is not a test */
63     {
64         trace("Can't get the surface description, hr=%s\n", DXGetErrorString9(hr));
65         return 0xdeadbeef;
66     }
67
68     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
69     if(FAILED(hr))  /* This is not a test */
70     {
71         trace("Can't lock the surface, hr=%s\n", DXGetErrorString9(hr));
72         return 0xdeadbeef;
73     }
74     switch(desc.Format) {
75         case D3DFMT_A8R8G8B8:
76         {
77             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
78             break;
79         }
80         default:
81             trace("Error: unknown surface format: %d\n", desc.Format);
82             color = 0xdeadbeef;
83             break;
84     }
85     hr = IDirect3DSurface9_UnlockRect(surface);
86     if(FAILED(hr))
87     {
88         trace("Can't unlock the surface, hr=%s\n", DXGetErrorString9(hr));
89     }
90     return color;
91 }
92
93 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
94 {
95     DWORD ret;
96     IDirect3DSurface9 *surf;
97     HRESULT hr;
98     D3DLOCKED_RECT lockedRect;
99     RECT rectToLock = {x, y, x+1, y+1};
100
101     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
102     if(FAILED(hr) || !surf )  /* This is not a test */
103     {
104         trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
105         return 0xdeadbeef;
106     }
107
108     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
109     if(FAILED(hr))
110     {
111         trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
112         ret = 0xdeadbeed;
113         goto out;
114     }
115
116     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
117     if(FAILED(hr))
118     {
119         trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
120         ret = 0xdeadbeec;
121         goto out;
122     }
123
124     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
125      * really important for these tests
126      */
127     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
128     hr = IDirect3DSurface9_UnlockRect(surf);
129     if(FAILED(hr))
130     {
131         trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
132     }
133
134 out:
135     if(surf) IDirect3DSurface9_Release(surf);
136     return ret;
137 }
138
139 static IDirect3DDevice9 *init_d3d9(void)
140 {
141     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
142     IDirect3D9 *d3d9_ptr = 0;
143     IDirect3DDevice9 *device_ptr = 0;
144     D3DPRESENT_PARAMETERS present_parameters;
145     HRESULT hr;
146
147     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
148     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
149     if (!d3d9_create) return NULL;
150
151     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
152     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
153     if (!d3d9_ptr) return NULL;
154
155     ZeroMemory(&present_parameters, sizeof(present_parameters));
156     present_parameters.Windowed = FALSE;
157     present_parameters.hDeviceWindow = create_window();
158     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
159     present_parameters.BackBufferWidth = 640;
160     present_parameters.BackBufferHeight = 480;
161     present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
162     present_parameters.EnableAutoDepthStencil = TRUE;
163     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
164
165     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
166     if(FAILED(hr)) {
167         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
168         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
169     }
170     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
171
172     return device_ptr;
173 }
174
175 struct vertex
176 {
177     float x, y, z;
178     DWORD diffuse;
179 };
180
181 struct tvertex
182 {
183     float x, y, z, rhw;
184     DWORD diffuse;
185 };
186
187 struct nvertex
188 {
189     float x, y, z;
190     float nx, ny, nz;
191     DWORD diffuse;
192 };
193
194 static void lighting_test(IDirect3DDevice9 *device)
195 {
196     HRESULT hr;
197     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
198     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
199     DWORD color;
200
201     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
202                       0.0f, 1.0f, 0.0f, 0.0f,
203                       0.0f, 0.0f, 1.0f, 0.0f,
204                       0.0f, 0.0f, 0.0f, 1.0f };
205
206     struct vertex unlitquad[] =
207     {
208         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
209         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
210         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
211         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
212     };
213     struct vertex litquad[] =
214     {
215         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
216         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
217         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
218         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
219     };
220     struct nvertex unlitnquad[] =
221     {
222         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
223         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
224         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
225         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
226     };
227     struct nvertex litnquad[] =
228     {
229         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
230         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
231         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
232         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
233     };
234     WORD Indices[] = {0, 1, 2, 2, 3, 0};
235
236     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
237     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
238
239     /* Setup some states that may cause issues */
240     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
241     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
242     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
243     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
244     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
245     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
246     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
247     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
248     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
249     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
250     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
251     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
252     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
253     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
254     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
255     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
256     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
257     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
258     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
259     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
260     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
261     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
262     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
263     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
264
265     hr = IDirect3DDevice9_SetFVF(device, fvf);
266     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
267
268     hr = IDirect3DDevice9_BeginScene(device);
269     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
270     if(hr == D3D_OK)
271     {
272         /* No lights are defined... That means, lit vertices should be entirely black */
273         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
274         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
275         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
276                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
277         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
278
279         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
280         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
281         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
282                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
283         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
284
285         hr = IDirect3DDevice9_SetFVF(device, nfvf);
286         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
287
288         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
289         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
290         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
291                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
292         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
293
294         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
295         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
296         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
297                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
298         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
299
300         IDirect3DDevice9_EndScene(device);
301         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
302     }
303
304     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
305
306     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
307     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
308     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
309     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
310     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
311     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
312     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
313     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
314
315     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
316     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
317 }
318
319 static void clear_test(IDirect3DDevice9 *device)
320 {
321     /* Tests the correctness of clearing parameters */
322     HRESULT hr;
323     D3DRECT rect[2];
324     D3DRECT rect_negneg;
325     DWORD color;
326     D3DVIEWPORT9 old_vp, vp;
327     RECT scissor;
328     DWORD oldColorWrite;
329     BOOL invalid_clear_failed = FALSE;
330
331     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
332     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
333
334     /* Positive x, negative y */
335     rect[0].x1 = 0;
336     rect[0].y1 = 480;
337     rect[0].x2 = 320;
338     rect[0].y2 = 240;
339
340     /* Positive x, positive y */
341     rect[1].x1 = 0;
342     rect[1].y1 = 0;
343     rect[1].x2 = 320;
344     rect[1].y2 = 240;
345     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
346      * returns D3D_OK, but ignores the rectangle silently
347      */
348     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
349     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
350     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
351
352     /* negative x, negative y */
353     rect_negneg.x1 = 640;
354     rect_negneg.y1 = 240;
355     rect_negneg.x2 = 320;
356     rect_negneg.y2 = 0;
357     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
358     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
359     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
360
361     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
362
363     color = getPixelColor(device, 160, 360); /* lower left quad */
364     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
365     color = getPixelColor(device, 160, 120); /* upper left quad */
366     if(invalid_clear_failed) {
367         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
368         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
369     } else {
370         /* If the negative rectangle was dropped silently, the correct ones are cleared */
371         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
372     }
373     color = getPixelColor(device, 480, 360); /* lower right quad  */
374     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
375     color = getPixelColor(device, 480, 120); /* upper right quad */
376     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
377
378     /* Test how the viewport affects clears */
379     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
380     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
381     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
382     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
383
384     vp.X = 160;
385     vp.Y = 120;
386     vp.Width = 160;
387     vp.Height = 120;
388     vp.MinZ = 0.0;
389     vp.MaxZ = 1.0;
390     hr = IDirect3DDevice9_SetViewport(device, &vp);
391     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
392     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
393     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
394
395     vp.X = 320;
396     vp.Y = 240;
397     vp.Width = 320;
398     vp.Height = 240;
399     vp.MinZ = 0.0;
400     vp.MaxZ = 1.0;
401     hr = IDirect3DDevice9_SetViewport(device, &vp);
402     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
403     rect[0].x1 = 160;
404     rect[0].y1 = 120;
405     rect[0].x2 = 480;
406     rect[0].y2 = 360;
407     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
408     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
409
410     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
411     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
412
413     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
414     color = getPixelColor(device, 158, 118);
415     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
416     color = getPixelColor(device, 162, 118);
417     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
418     color = getPixelColor(device, 158, 122);
419     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
420     color = getPixelColor(device, 162, 122);
421     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
422
423     color = getPixelColor(device, 318, 238);
424     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
425     color = getPixelColor(device, 322, 238);
426     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
427     color = getPixelColor(device, 318, 242);
428     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
429     color = getPixelColor(device, 322, 242);
430     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
431
432     color = getPixelColor(device, 478, 358);
433     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
434     color = getPixelColor(device, 482, 358);
435     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
436     color = getPixelColor(device, 478, 362);
437     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
438     color = getPixelColor(device, 482, 362);
439     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
440
441     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
442     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
443
444     scissor.left = 160;
445     scissor.right = 480;
446     scissor.top = 120;
447     scissor.bottom = 360;
448     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
449     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
450     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
451     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
452
453     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
454     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
455     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
456     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
457
458     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
459     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
460
461     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
462     color = getPixelColor(device, 158, 118);
463     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
464     color = getPixelColor(device, 162, 118);
465     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
466     color = getPixelColor(device, 158, 122);
467     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
468     color = getPixelColor(device, 162, 122);
469     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
470
471     color = getPixelColor(device, 158, 358);
472     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
473     color = getPixelColor(device, 162, 358);
474     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
475     color = getPixelColor(device, 158, 358);
476     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
477     color = getPixelColor(device, 162, 362);
478     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
479
480     color = getPixelColor(device, 478, 118);
481     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
482     color = getPixelColor(device, 478, 122);
483     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
484     color = getPixelColor(device, 482, 122);
485     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
486     color = getPixelColor(device, 482, 358);
487     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
488
489     color = getPixelColor(device, 478, 358);
490     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
491     color = getPixelColor(device, 478, 362);
492     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
493     color = getPixelColor(device, 482, 358);
494     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
495     color = getPixelColor(device, 482, 362);
496     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
497
498     color = getPixelColor(device, 318, 238);
499     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
500     color = getPixelColor(device, 318, 242);
501     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
502     color = getPixelColor(device, 322, 238);
503     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
504     color = getPixelColor(device, 322, 242);
505     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
506
507     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
508     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
511
512     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
513     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
514
515     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
517
518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
519
520     /* Colorwriteenable does not affect the clear */
521     color = getPixelColor(device, 320, 240);
522     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
523 }
524
525 typedef struct {
526     float in[4];
527     DWORD out;
528 } test_data_t;
529
530 /*
531  *  c7      mova    ARGB            mov     ARGB
532  * -2.4     -2      0x00ffff00      -3      0x00ff0000
533  * -1.6     -2      0x00ffff00      -2      0x00ffff00
534  * -0.4      0      0x0000ffff      -1      0x0000ff00
535  *  0.4      0      0x0000ffff       0      0x0000ffff
536  *  1.6      2      0x00ff00ff       1      0x000000ff
537  *  2.4      2      0x00ff00ff       2      0x00ff00ff
538  */
539 static void test_mova(IDirect3DDevice9 *device)
540 {
541     static const DWORD mova_test[] = {
542         0xfffe0200,                                                             /* vs_2_0                       */
543         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
544         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
545         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
546         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
547         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
548         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
549         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
550         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
551         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
552         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
553         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
554         0x0000ffff                                                              /* END                          */
555     };
556     static const DWORD mov_test[] = {
557         0xfffe0101,                                                             /* vs_1_1                       */
558         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
559         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
560         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
561         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
562         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
563         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
564         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
565         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
566         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
567         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
568         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
569         0x0000ffff                                                              /* END                          */
570     };
571
572     static const test_data_t test_data[2][6] = {
573         {
574             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
575             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
576             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
577             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
578             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
579             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
580         },
581         {
582             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
583             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
584             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
585             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
586             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
587             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
588         }
589     };
590
591     static const float quad[][3] = {
592         {-1.0f, -1.0f, 0.0f},
593         {-1.0f,  1.0f, 0.0f},
594         { 1.0f, -1.0f, 0.0f},
595         { 1.0f,  1.0f, 0.0f},
596     };
597
598     static const D3DVERTEXELEMENT9 decl_elements[] = {
599         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
600         D3DDECL_END()
601     };
602
603     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
604     IDirect3DVertexShader9 *mova_shader = NULL;
605     IDirect3DVertexShader9 *mov_shader = NULL;
606     HRESULT hr;
607     UINT i, j;
608
609     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
610     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
611     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
612     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
613     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
614     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
615     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
616     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
617
618     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
619     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
620     for(j = 0; j < 2; ++j)
621     {
622         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
623         {
624             DWORD color;
625
626             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
627             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
628
629             hr = IDirect3DDevice9_BeginScene(device);
630             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
631
632             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
633             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
634
635             hr = IDirect3DDevice9_EndScene(device);
636             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
637
638             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
639             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
640
641             color = getPixelColor(device, 320, 240);
642             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
643                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
644
645             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
646             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
647         }
648         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
649         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
650     }
651
652     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
653     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
654
655     IDirect3DVertexDeclaration9_Release(vertex_declaration);
656     IDirect3DVertexShader9_Release(mova_shader);
657     IDirect3DVertexShader9_Release(mov_shader);
658 }
659
660 struct sVertex {
661     float x, y, z;
662     DWORD diffuse;
663     DWORD specular;
664 };
665
666 struct sVertexT {
667     float x, y, z, rhw;
668     DWORD diffuse;
669     DWORD specular;
670 };
671
672 static void fog_test(IDirect3DDevice9 *device)
673 {
674     HRESULT hr;
675     DWORD color;
676     BYTE r, g, b;
677     float start = 0.0f, end = 1.0f;
678     D3DCAPS9 caps;
679     int i;
680
681     /* Gets full z based fog with linear fog, no fog with specular color */
682     struct sVertex unstransformed_1[] = {
683         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
684         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
685         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
686         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
687     };
688     /* Ok, I am too lazy to deal with transform matrices */
689     struct sVertex unstransformed_2[] = {
690         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
691         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
692         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
693         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
694     };
695     /* Untransformed ones. Give them a different diffuse color to make the test look
696      * nicer. It also makes making sure that they are drawn correctly easier.
697      */
698     struct sVertexT transformed_1[] = {
699         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
700         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
701         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
702         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
703     };
704     struct sVertexT transformed_2[] = {
705         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
706         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
707         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
708         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
709     };
710     struct vertex rev_fog_quads[] = {
711        {-1.0,   -1.0,   0.1,    0x000000ff},
712        {-1.0,    0.0,   0.1,    0x000000ff},
713        { 0.0,    0.0,   0.1,    0x000000ff},
714        { 0.0,   -1.0,   0.1,    0x000000ff},
715
716        { 0.0,   -1.0,   0.9,    0x000000ff},
717        { 0.0,    0.0,   0.9,    0x000000ff},
718        { 1.0,    0.0,   0.9,    0x000000ff},
719        { 1.0,   -1.0,   0.9,    0x000000ff},
720
721        { 0.0,    0.0,   0.4,    0x000000ff},
722        { 0.0,    1.0,   0.4,    0x000000ff},
723        { 1.0,    1.0,   0.4,    0x000000ff},
724        { 1.0,    0.0,   0.4,    0x000000ff},
725
726        {-1.0,    0.0,   0.7,    0x000000ff},
727        {-1.0,    1.0,   0.7,    0x000000ff},
728        { 0.0,    1.0,   0.7,    0x000000ff},
729        { 0.0,    0.0,   0.7,    0x000000ff},
730     };
731     WORD Indices[] = {0, 1, 2, 2, 3, 0};
732
733     memset(&caps, 0, sizeof(caps));
734     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
735     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
736     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
737     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
738
739     /* Setup initial states: No lighting, fog on, fog color */
740     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
741     ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
742     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
743     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
744     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
745     ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
746
747     /* First test: Both table fog and vertex fog off */
748     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
749     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
750     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
751     ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
752
753     /* Start = 0, end = 1. Should be default, but set them */
754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
755     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
757     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
758
759     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
760     {
761         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
762         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
763         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
764         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
765                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
766                                                      sizeof(unstransformed_1[0]));
767         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
768
769         /* That makes it use the Z value */
770         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
771         ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
772         /* Untransformed, vertex fog != none (or table fog != none):
773          * Use the Z value as input into the equation
774          */
775         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
776                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
777                                                      sizeof(unstransformed_1[0]));
778         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
779
780         /* transformed verts */
781         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
782         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
783         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
784         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
785                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
786                                                      sizeof(transformed_1[0]));
787         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
788
789         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
790         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
791         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
792          * equation
793          */
794         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
795                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
796                                                      sizeof(transformed_2[0]));
797
798         hr = IDirect3DDevice9_EndScene(device);
799         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
800     }
801     else
802     {
803         ok(FALSE, "BeginScene failed\n");
804     }
805
806     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
807     color = getPixelColor(device, 160, 360);
808     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
809     color = getPixelColor(device, 160, 120);
810     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
811     color = getPixelColor(device, 480, 120);
812     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
813     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
814     {
815         color = getPixelColor(device, 480, 360);
816         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
817     }
818     else
819     {
820         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
821          * The settings above result in no fogging with vertex fog
822          */
823         color = getPixelColor(device, 480, 120);
824         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
825         trace("Info: Table fog not supported by this device\n");
826     }
827
828     /* Now test the special case fogstart == fogend */
829     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
830     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
831
832     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
833     {
834         start = 512;
835         end = 512;
836         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
837         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
838         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
839         ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
840
841         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
842         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
843         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
844         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
845         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
846         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
847
848         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
849          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
850          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
851          * The third transformed quad remains unfogged because the fogcoords are read from the specular
852          * color and has fixed fogstart and fogend.
853          */
854         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
855                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
856                 sizeof(unstransformed_1[0]));
857         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
858         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
859                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
860                 sizeof(unstransformed_1[0]));
861         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
862
863         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
864         ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
865         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
866         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
867                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
868                 sizeof(transformed_1[0]));
869         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
870
871         hr = IDirect3DDevice9_EndScene(device);
872         ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
873     }
874     else
875     {
876         ok(FALSE, "BeginScene failed\n");
877     }
878     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
879     color = getPixelColor(device, 160, 360);
880     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
881     color = getPixelColor(device, 160, 120);
882     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
883     color = getPixelColor(device, 480, 120);
884     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
885
886     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
887      * but without shaders it seems to work everywhere
888      */
889     end = 0.2;
890     start = 0.8;
891     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
892     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
893     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
894     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
895     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
896     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
897
898     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
899      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
900      * so skip this for now
901      */
902     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
903         const char *mode = (i ? "table" : "vertex");
904         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
905         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
906         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
907         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
908         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
909         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
910         hr = IDirect3DDevice9_BeginScene(device);
911         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
912         if(SUCCEEDED(hr)) {
913             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
914                                 4,  5,  6,  6,  7, 4,
915                                 8,  9, 10, 10, 11, 8,
916                             12, 13, 14, 14, 15, 12};
917
918             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
919                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
920                     sizeof(rev_fog_quads[0]));
921
922             hr = IDirect3DDevice9_EndScene(device);
923             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
924         }
925         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
926         color = getPixelColor(device, 160, 360);
927         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
928
929         color = getPixelColor(device, 160, 120);
930         r = (color & 0x00ff0000) >> 16;
931         g = (color & 0x0000ff00) >>  8;
932         b = (color & 0x000000ff);
933         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
934            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
935
936         color = getPixelColor(device, 480, 120);
937         r = (color & 0x00ff0000) >> 16;
938         g = (color & 0x0000ff00) >>  8;
939         b = (color & 0x000000ff);
940         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
941            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
942
943         color = getPixelColor(device, 480, 360);
944         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
945
946         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
947             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
948             break;
949         }
950     }
951     /* Turn off the fog master switch to avoid confusing other tests */
952     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
953     ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
954     start = 0.0;
955     end = 1.0;
956     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
957     ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
958     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
959     ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
960     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
961     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
962     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
963     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
964 }
965
966 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
967  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
968  * regardless of the actual addressing mode set. */
969 static void test_cube_wrap(IDirect3DDevice9 *device)
970 {
971     static const float quad[][6] = {
972         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
973         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
974         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
975         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
976     };
977
978     static const D3DVERTEXELEMENT9 decl_elements[] = {
979         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
980         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
981         D3DDECL_END()
982     };
983
984     static const struct {
985         D3DTEXTUREADDRESS mode;
986         const char *name;
987     } address_modes[] = {
988         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
989         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
990         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
991         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
992         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
993     };
994
995     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
996     IDirect3DCubeTexture9 *texture = NULL;
997     IDirect3DSurface9 *surface = NULL;
998     D3DLOCKED_RECT locked_rect;
999     HRESULT hr;
1000     UINT x;
1001     INT y, face;
1002
1003     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1004     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1005     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1006     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1007
1008     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1009             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1010     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1011
1012     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1013     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1014
1015     for (y = 0; y < 128; ++y)
1016     {
1017         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1018         for (x = 0; x < 64; ++x)
1019         {
1020             *ptr++ = 0xffff0000;
1021         }
1022         for (x = 64; x < 128; ++x)
1023         {
1024             *ptr++ = 0xff0000ff;
1025         }
1026     }
1027
1028     hr = IDirect3DSurface9_UnlockRect(surface);
1029     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1030
1031     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1032             D3DPOOL_DEFAULT, &texture, NULL);
1033     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1034
1035     /* Create cube faces */
1036     for (face = 0; face < 6; ++face)
1037     {
1038         IDirect3DSurface9 *face_surface = NULL;
1039
1040         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1041         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1042
1043         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1044         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1045
1046         IDirect3DSurface9_Release(face_surface);
1047     }
1048
1049     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1050     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1051
1052     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1053     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1054     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1055     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1056     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1057     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1058
1059     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1060     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1061
1062     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1063     {
1064         DWORD color;
1065
1066         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1067         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1068         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1069         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1070
1071         hr = IDirect3DDevice9_BeginScene(device);
1072         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1073
1074         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1075         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1076
1077         hr = IDirect3DDevice9_EndScene(device);
1078         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1079
1080         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1081         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1082
1083         /* Due to the nature of this test, we sample essentially at the edge
1084          * between two faces. Because of this it's undefined from which face
1085          * the driver will sample. Fortunately that's not important for this
1086          * test, since all we care about is that it doesn't sample from the
1087          * other side of the surface or from the border. */
1088         color = getPixelColor(device, 320, 240);
1089         ok(color == 0x00ff0000 || color == 0x000000ff,
1090                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1091                 color, address_modes[x].name);
1092
1093         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1094         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1095     }
1096
1097     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1098     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1099
1100     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1101     IDirect3DCubeTexture9_Release(texture);
1102     IDirect3DSurface9_Release(surface);
1103 }
1104
1105 static void offscreen_test(IDirect3DDevice9 *device)
1106 {
1107     HRESULT hr;
1108     IDirect3DTexture9 *offscreenTexture = NULL;
1109     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1110     DWORD color;
1111
1112     static const float quad[][5] = {
1113         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1114         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1115         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1116         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1117     };
1118
1119     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1120     ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1121
1122     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1123     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1124     if(!offscreenTexture) {
1125         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1126         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1127         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1128         if(!offscreenTexture) {
1129             skip("Cannot create an offscreen render target\n");
1130             goto out;
1131         }
1132     }
1133
1134     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1135     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1136     if(!backbuffer) {
1137         goto out;
1138     }
1139
1140     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1141     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1142     if(!offscreen) {
1143         goto out;
1144     }
1145
1146     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1147     ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1148
1149     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1150     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1151     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1152     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1153     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1154     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1155     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1156     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1157     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1158     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1159
1160     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1161         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1162         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1163         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1164         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1165
1166         /* Draw without textures - Should result in a white quad */
1167         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1168         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1169
1170         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1171         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1172         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1173         ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1174
1175         /* This time with the texture */
1176         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1177         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1178
1179         IDirect3DDevice9_EndScene(device);
1180     }
1181
1182     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1183
1184     /* Center quad - should be white */
1185     color = getPixelColor(device, 320, 240);
1186     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1187     /* Some quad in the cleared part of the texture */
1188     color = getPixelColor(device, 170, 240);
1189     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1190     /* Part of the originally cleared back buffer */
1191     color = getPixelColor(device, 10, 10);
1192     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1193     if(0) {
1194         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1195          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1196          * the offscreen rendering mode this test would succeed or fail
1197          */
1198         color = getPixelColor(device, 10, 470);
1199         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1200     }
1201
1202 out:
1203     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1204
1205     /* restore things */
1206     if(backbuffer) {
1207         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1208         IDirect3DSurface9_Release(backbuffer);
1209     }
1210     if(offscreenTexture) {
1211         IDirect3DTexture9_Release(offscreenTexture);
1212     }
1213     if(offscreen) {
1214         IDirect3DSurface9_Release(offscreen);
1215     }
1216 }
1217
1218 /* This test tests fog in combination with shaders.
1219  * What's tested: linear fog (vertex and table) with pixel shader
1220  *                linear table fog with non foggy vertex shader
1221  *                vertex fog with foggy vertex shader
1222  * What's not tested: non linear fog with shader
1223  *                    table fog with foggy vertex shader
1224  */
1225 static void fog_with_shader_test(IDirect3DDevice9 *device)
1226 {
1227     HRESULT hr;
1228     DWORD color;
1229     union {
1230         float f;
1231         DWORD i;
1232     } start, end;
1233     unsigned int i, j;
1234
1235     /* basic vertex shader without fog computation ("non foggy") */
1236     static const DWORD vertex_shader_code1[] = {
1237         0xfffe0101,                                                             /* vs_1_1                       */
1238         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1239         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1240         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1241         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1242         0x0000ffff
1243     };
1244     /* basic vertex shader with reversed fog computation ("foggy") */
1245     static const DWORD vertex_shader_code2[] = {
1246         0xfffe0101,                                                             /* vs_1_1                        */
1247         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1248         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1249         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1250         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1251         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1252         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1253         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1254         0x0000ffff
1255     };
1256     /* basic pixel shader */
1257     static const DWORD pixel_shader_code[] = {
1258         0xffff0101,                                                             /* ps_1_1     */
1259         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1260         0x0000ffff
1261     };
1262
1263     static struct vertex quad[] = {
1264         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1265         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1266         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1267         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1268     };
1269
1270     static const D3DVERTEXELEMENT9 decl_elements[] = {
1271         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1272         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1273         D3DDECL_END()
1274     };
1275
1276     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1277     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1278     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1279
1280     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1281     static const struct test_data_t {
1282         int vshader;
1283         int pshader;
1284         D3DFOGMODE vfog;
1285         D3DFOGMODE tfog;
1286         unsigned int color[11];
1287     } test_data[] = {
1288         /* only pixel shader: */
1289         {0, 1, 0, 3,
1290         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1291         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1292         {0, 1, 1, 3,
1293         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1294         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1295         {0, 1, 2, 3,
1296         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1297         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1298         {0, 1, 3, 0,
1299         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1300         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1301         {0, 1, 3, 3,
1302         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1303         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1304
1305         /* vertex shader */
1306         {1, 0, 0, 0,
1307         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1308          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1309         {1, 0, 0, 3,
1310         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1311         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1312         {1, 0, 1, 3,
1313         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1314         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1315
1316         {1, 0, 2, 3,
1317         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1318         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1319         {1, 0, 3, 3,
1320         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1321         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1322
1323         /* vertex shader and pixel shader */
1324         {1, 1, 0, 3,
1325         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1326         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1327         {1, 1, 1, 3,
1328         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1329         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1330         {1, 1, 2, 3,
1331         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1332         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1333
1334         {1, 1, 3, 3,
1335         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1336         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1337
1338
1339 #if 0  /* FIXME: these fail on GeForce 8500 */
1340         /* foggy vertex shader */
1341         {2, 0, 0, 0,
1342         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1343          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1344         {2, 0, 1, 0,
1345         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1346          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1347         {2, 0, 2, 0,
1348         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1349          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1350         {2, 0, 3, 0,
1351         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1352          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1353 #endif
1354
1355         /* foggy vertex shader and pixel shader */
1356         {2, 1, 0, 0,
1357         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1358          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1359         {2, 1, 1, 0,
1360         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1361          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1362         {2, 1, 2, 0,
1363         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1364          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1365         {2, 1, 3, 0,
1366         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1367          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1368
1369     };
1370
1371     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1372     start.f=0.1f;
1373     end.f=0.9f;
1374
1375     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1376     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1377     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1378     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1379     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1380     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1381     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1382     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1383
1384     /* Setup initial states: No lighting, fog on, fog color */
1385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1386     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1387     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1388     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1389     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1390     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1391     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1392     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1393
1394     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1395     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1396     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1397     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1398
1399     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1400     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1401     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1402     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1403     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1404
1405     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1406     {
1407         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1408         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1409         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1410         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1411         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1412         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1413         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1414         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1415
1416         for(j=0; j < 11; j++)
1417         {
1418             /* Don't use the whole zrange to prevent rounding errors */
1419             quad[0].z = 0.001f + (float)j / 10.02f;
1420             quad[1].z = 0.001f + (float)j / 10.02f;
1421             quad[2].z = 0.001f + (float)j / 10.02f;
1422             quad[3].z = 0.001f + (float)j / 10.02f;
1423
1424             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1425             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1426
1427             hr = IDirect3DDevice9_BeginScene(device);
1428             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1429
1430             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1431             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1432
1433             hr = IDirect3DDevice9_EndScene(device);
1434             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1435
1436             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1437
1438             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1439             color = getPixelColor(device, 128, 240);
1440             ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1441                     && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1442                     && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1443                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1444                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1445         }
1446     }
1447
1448     /* reset states */
1449     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1450     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1451     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1452     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1453     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1454     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1455     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1456     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1457
1458     IDirect3DVertexShader9_Release(vertex_shader[1]);
1459     IDirect3DVertexShader9_Release(vertex_shader[2]);
1460     IDirect3DPixelShader9_Release(pixel_shader[1]);
1461     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1462 }
1463
1464 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1465     unsigned int i, x, y;
1466     HRESULT hr;
1467     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1468     D3DLOCKED_RECT locked_rect;
1469
1470     /* Generate the textures */
1471     for(i=0; i<2; i++)
1472     {
1473         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1474                                             D3DPOOL_MANAGED, &texture[i], NULL);
1475         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1476
1477         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1478         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1479         for (y = 0; y < 128; ++y)
1480         {
1481             if(i)
1482             { /* Set up black texture with 2x2 texel white spot in the middle */
1483                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1484                 for (x = 0; x < 128; ++x)
1485                 {
1486                     if(y>62 && y<66 && x>62 && x<66)
1487                         *ptr++ = 0xffffffff;
1488                     else
1489                         *ptr++ = 0xff000000;
1490                 }
1491             }
1492             else
1493             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1494                * (if multiplied with bumpenvmat)
1495               */
1496                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1497                 for (x = 0; x < 128; ++x)
1498                 {
1499                     if(abs(x-64)>abs(y-64))
1500                     {
1501                         if(x < 64)
1502                             *ptr++ = 0xc000;
1503                         else
1504                             *ptr++ = 0x4000;
1505                     }
1506                     else
1507                     {
1508                         if(y < 64)
1509                             *ptr++ = 0x0040;
1510                         else
1511                             *ptr++ = 0x00c0;
1512                     }
1513                 }
1514             }
1515         }
1516         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1517         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1518
1519         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1520         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1521
1522         /* Disable texture filtering */
1523         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1524         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1525         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1526         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1527
1528         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1529         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1530         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1531         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1532     }
1533 }
1534
1535 /* test the behavior of the texbem instruction
1536  * with normal 2D and projective 2D textures
1537  */
1538 static void texbem_test(IDirect3DDevice9 *device)
1539 {
1540     HRESULT hr;
1541     DWORD color;
1542     int i;
1543
1544     static const DWORD pixel_shader_code[] = {
1545         0xffff0101,                         /* ps_1_1*/
1546         0x00000042, 0xb00f0000,             /* tex t0*/
1547         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1548         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1549         0x0000ffff
1550     };
1551     static const DWORD double_texbem_code[] =  {
1552         0xffff0103,                                         /* ps_1_3           */
1553         0x00000042, 0xb00f0000,                             /* tex t0           */
1554         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1555         0x00000042, 0xb00f0002,                             /* tex t2           */
1556         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1557         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1558         0x0000ffff                                          /* end              */
1559     };
1560
1561
1562     static const float quad[][7] = {
1563         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1564         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1565         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1566         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1567     };
1568     static const float quad_proj[][9] = {
1569         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1570         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1571         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1572         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1573     };
1574
1575     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1576         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1577         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1578         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1579         D3DDECL_END()
1580     },{
1581         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1582         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1583         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1584         D3DDECL_END()
1585     } };
1586
1587     /* use asymmetric matrix to test loading */
1588     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1589
1590     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1591     IDirect3DPixelShader9       *pixel_shader       = NULL;
1592     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1593     D3DLOCKED_RECT locked_rect;
1594
1595     generate_bumpmap_textures(device);
1596
1597     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1598     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1599     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1600     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1601     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1602
1603     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1604     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1605
1606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1608
1609     for(i=0; i<2; i++)
1610     {
1611         if(i)
1612         {
1613             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1614             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1615         }
1616
1617         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1618         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1619         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1620         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1621
1622         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1623         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1624         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1625         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1626
1627         hr = IDirect3DDevice9_BeginScene(device);
1628         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1629
1630         if(!i)
1631             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1632         else
1633             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1634         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1635
1636         hr = IDirect3DDevice9_EndScene(device);
1637         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1638
1639         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1640         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1641
1642         color = getPixelColor(device, 320-32, 240);
1643         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1644         color = getPixelColor(device, 320+32, 240);
1645         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1646         color = getPixelColor(device, 320, 240-32);
1647         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1648         color = getPixelColor(device, 320, 240+32);
1649         ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1650
1651         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1652         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1653         IDirect3DPixelShader9_Release(pixel_shader);
1654
1655         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1656         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1657         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1658     }
1659
1660     /* clean up */
1661     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1662     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1663
1664     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1665     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1666
1667     for(i=0; i<2; i++)
1668     {
1669         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1670         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1671         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1672         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1673         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1674         IDirect3DTexture9_Release(texture);
1675     }
1676
1677     /* Test double texbem */
1678     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1679     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1680     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1681     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1682     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1683     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1684     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1685     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1686
1687     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1688     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1689     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1690     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1691
1692     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1693     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1694
1695     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1696     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1697     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1698     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1699     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1700     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1701
1702     {
1703         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1704 #define tex  0x00ff0000
1705 #define tex1 0x0000ff00
1706 #define origin 0x000000ff
1707         static const DWORD pixel_data[] = {
1708             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1709             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1710             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1711             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1712             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1713             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1714             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1715             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1716         };
1717 #undef tex1
1718 #undef tex2
1719 #undef origin
1720
1721         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1722         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1723         for(i = 0; i < 8; i++) {
1724             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1725         }
1726         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1727         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1728     }
1729
1730     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1731     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1732     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1733     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1734     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1735     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1736     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1737     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1738     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1739     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1740     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1741     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1742
1743     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1744     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1745     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1746     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1747     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1748     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1749
1750     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1751     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1752     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1753     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1754     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1755     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1756
1757     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1758     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1759     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1760     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1761     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1762     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1763     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1764     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1765
1766     hr = IDirect3DDevice9_BeginScene(device);
1767     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1768     if(SUCCEEDED(hr)) {
1769         static const float double_quad[] = {
1770             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1771              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1772             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1773              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1774         };
1775
1776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1777         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1778         hr = IDirect3DDevice9_EndScene(device);
1779         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1780     }
1781     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1782     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1783     color = getPixelColor(device, 320, 240);
1784     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1785
1786     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1787     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1788     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1789     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1790     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1791     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1792     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1793     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1794     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1795     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1796
1797     IDirect3DPixelShader9_Release(pixel_shader);
1798     IDirect3DTexture9_Release(texture);
1799     IDirect3DTexture9_Release(texture1);
1800     IDirect3DTexture9_Release(texture2);
1801 }
1802
1803 static void z_range_test(IDirect3DDevice9 *device)
1804 {
1805     const struct vertex quad[] =
1806     {
1807         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1808         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1809         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1810         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1811     };
1812     const struct vertex quad2[] =
1813     {
1814         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1815         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1816         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1817         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1818     };
1819
1820     const struct tvertex quad3[] =
1821     {
1822         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1823         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1824         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1825         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1826     };
1827     const struct tvertex quad4[] =
1828     {
1829         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1830         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1831         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1832         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1833     };
1834     HRESULT hr;
1835     DWORD color;
1836     IDirect3DVertexShader9 *shader;
1837     IDirect3DVertexDeclaration9 *decl;
1838     D3DCAPS9 caps;
1839     const DWORD shader_code[] = {
1840         0xfffe0101,                                     /* vs_1_1           */
1841         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1842         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1843         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1844         0x0000ffff                                      /* end              */
1845     };
1846     static const D3DVERTEXELEMENT9 decl_elements[] = {
1847         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1848         D3DDECL_END()
1849     };
1850     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1851      * then call Present. Then clear the color buffer to make sure it has some defined content
1852      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1853      * by the depth value.
1854      */
1855     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1856     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1857     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1858     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1859
1860     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1861     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1862     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1863     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1864     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1865     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1866     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1867     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1868     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1869     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1870
1871     hr = IDirect3DDevice9_BeginScene(device);
1872     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1873     if(hr == D3D_OK)
1874     {
1875         /* Test the untransformed vertex path */
1876         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1877         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1878         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1879         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1880         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1881         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1882
1883         /* Test the transformed vertex path */
1884         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1885         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1886
1887         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1888         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1889         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1890         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1891         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1892         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1893
1894         hr = IDirect3DDevice9_EndScene(device);
1895         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1896     }
1897
1898     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1899     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1900
1901     /* Do not test the exact corner pixels, but go pretty close to them */
1902
1903     /* Clipped because z > 1.0 */
1904     color = getPixelColor(device, 28, 238);
1905     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1906     color = getPixelColor(device, 28, 241);
1907     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1908
1909     /* Not clipped, > z buffer clear value(0.75) */
1910     color = getPixelColor(device, 31, 238);
1911     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1912     color = getPixelColor(device, 31, 241);
1913     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1914     color = getPixelColor(device, 100, 238);
1915     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1916     color = getPixelColor(device, 100, 241);
1917     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1918
1919     /* Not clipped, < z buffer clear value */
1920     color = getPixelColor(device, 104, 238);
1921     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1922     color = getPixelColor(device, 104, 241);
1923     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1924     color = getPixelColor(device, 318, 238);
1925     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1926     color = getPixelColor(device, 318, 241);
1927     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1928
1929     /* Clipped because z < 0.0 */
1930     color = getPixelColor(device, 321, 238);
1931     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1932     color = getPixelColor(device, 321, 241);
1933     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1934
1935     /* Test the shader path */
1936     IDirect3DDevice9_GetDeviceCaps(device, &caps);
1937     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1938         skip("Vertex shaders not supported\n");
1939         goto out;
1940     }
1941     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1942     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1943     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1944     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1945
1946     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1947
1948     IDirect3DDevice9_SetVertexDeclaration(device, decl);
1949     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1950     IDirect3DDevice9_SetVertexShader(device, shader);
1951     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1952
1953     hr = IDirect3DDevice9_BeginScene(device);
1954     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1955     if(hr == D3D_OK)
1956     {
1957         float colorf[] = {1.0, 0.0, 0.0, 1.0};
1958         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1959         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1961         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1962         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1963         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1964         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1965         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1966         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1967
1968         hr = IDirect3DDevice9_EndScene(device);
1969         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1970     }
1971
1972     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1973     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1974     IDirect3DDevice9_SetVertexShader(device, NULL);
1975     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1976
1977     IDirect3DVertexDeclaration9_Release(decl);
1978     IDirect3DVertexShader9_Release(shader);
1979
1980     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1981     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1982     /* Z < 1.0 */
1983     color = getPixelColor(device, 28, 238);
1984     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1985
1986     /* 1.0 < z < 0.75 */
1987     color = getPixelColor(device, 31, 238);
1988     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1989     color = getPixelColor(device, 100, 238);
1990     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1991
1992     /* 0.75 < z < 0.0 */
1993     color = getPixelColor(device, 104, 238);
1994     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1995     color = getPixelColor(device, 318, 238);
1996     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1997
1998     /* 0.0 < z */
1999     color = getPixelColor(device, 321, 238);
2000     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2001
2002     out:
2003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2004     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2006     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2007     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2008     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2009 }
2010
2011 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2012 {
2013     D3DSURFACE_DESC desc;
2014     D3DLOCKED_RECT l;
2015     HRESULT hr;
2016     unsigned int x, y;
2017     DWORD *mem;
2018
2019     memset(&desc, 0, sizeof(desc));
2020     memset(&l, 0, sizeof(l));
2021     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2022     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2023     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2024     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2025     if(FAILED(hr)) return;
2026
2027     for(y = 0; y < desc.Height; y++)
2028     {
2029         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2030         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2031         {
2032             mem[x] = color;
2033         }
2034     }
2035     hr = IDirect3DSurface9_UnlockRect(surface);
2036     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2037 }
2038
2039 /* This tests a variety of possible StretchRect() situations */
2040 static void stretchrect_test(IDirect3DDevice9 *device)
2041 {
2042     HRESULT hr;
2043     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64;
2044     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64;
2045     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2046     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2047     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2048     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2049     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2050     IDirect3DSurface9 *orig_rt = NULL;
2051     DWORD color;
2052
2053     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2054     ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2055     if(!orig_rt) {
2056         goto out;
2057     }
2058
2059     /* Create our temporary surfaces in system memory */
2060     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2061     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2062     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2063     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2064
2065     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2066     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2067     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2068     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2069     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2070     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2071     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2072
2073     /* Create render target surfaces */
2074     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2075     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2076     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2077     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2078     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2079     ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2080
2081     /* Create render target textures */
2082     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2083     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2084     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2085     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2086     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2087     ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2088     if (tex_rt32) {
2089         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2090         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2091     }
2092     if (tex_rt64) {
2093         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2094         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2095     }
2096     if (tex_rt_dest64) {
2097         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2098         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2099     }
2100
2101     /* Create regular textures in D3DPOOL_DEFAULT */
2102     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2103     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2104     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2105     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2106     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2107     ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2108     if (tex32) {
2109         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2110         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2111     }
2112     if (tex64) {
2113         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2114         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2115     }
2116     if (tex_dest64) {
2117         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2118         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2119     }
2120
2121     /*********************************************************************
2122      * Tests for when the source parameter is an offscreen plain surface *
2123      *********************************************************************/
2124
2125     /* Fill the offscreen 64x64 surface with green */
2126     if (surf_offscreen64)
2127         fill_surface(surf_offscreen64, 0xff00ff00);
2128
2129     /* offscreenplain ==> offscreenplain, same size */
2130     if(surf_offscreen64 && surf_offscreen_dest64) {
2131         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2132         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2133
2134         if (hr == D3D_OK) {
2135             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2136             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2137         }
2138     }
2139
2140     /* offscreenplain ==> rendertarget texture, same size */
2141     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2142         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2143         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2144
2145         /* We can't lock rendertarget textures, so copy to our temp surface first */
2146         if (hr == D3D_OK) {
2147             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2148             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2149         }
2150
2151         if (hr == D3D_OK) {
2152             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2153             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2154         }
2155     }
2156
2157     /* offscreenplain ==> rendertarget surface, same size */
2158     if(surf_offscreen64 && surf_rt_dest64) {
2159         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2160         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2161
2162         if (hr == D3D_OK) {
2163             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2164             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2165         }
2166     }
2167
2168     /* offscreenplain ==> texture, same size (should fail) */
2169     if(surf_offscreen64 && surf_tex_dest64) {
2170         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2171         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2172     }
2173
2174     /* Fill the smaller offscreen surface with red */
2175     fill_surface(surf_offscreen32, 0xffff0000);
2176
2177     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2178     if(surf_offscreen32 && surf_offscreen64) {
2179         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2180         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2181     }
2182
2183     /* offscreenplain ==> rendertarget texture, scaling */
2184     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2185         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2186         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2187
2188         /* We can't lock rendertarget textures, so copy to our temp surface first */
2189         if (hr == D3D_OK) {
2190             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2191             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2192         }
2193
2194         if (hr == D3D_OK) {
2195             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2196             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2197         }
2198     }
2199
2200     /* offscreenplain ==> rendertarget surface, scaling */
2201     if(surf_offscreen32 && surf_rt_dest64) {
2202         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2203         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2204
2205         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2206         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2207     }
2208
2209     /* offscreenplain ==> texture, scaling (should fail) */
2210     if(surf_offscreen32 && surf_tex_dest64) {
2211         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2212         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2213     }
2214
2215     /************************************************************
2216      * Tests for when the source parameter is a regular texture *
2217      ************************************************************/
2218
2219     /* Fill the surface of the regular texture with blue */
2220     if (surf_tex64 && surf_temp64) {
2221         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2222         fill_surface(surf_temp64, 0xff0000ff);
2223         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2224         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2225     }
2226
2227     /* texture ==> offscreenplain, same size */
2228     if(surf_tex64 && surf_offscreen64) {
2229         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2230         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2231     }
2232
2233     /* texture ==> rendertarget texture, same size */
2234     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2235         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2236         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2237
2238         /* We can't lock rendertarget textures, so copy to our temp surface first */
2239         if (hr == D3D_OK) {
2240             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2241             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2242         }
2243
2244         if (hr == D3D_OK) {
2245             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2246             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2247         }
2248     }
2249
2250     /* texture ==> rendertarget surface, same size */
2251     if(surf_tex64 && surf_rt_dest64) {
2252         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2253         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2254
2255         if (hr == D3D_OK) {
2256             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2257             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2258         }
2259     }
2260
2261     /* texture ==> texture, same size (should fail) */
2262     if(surf_tex64 && surf_tex_dest64) {
2263         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2264         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2265     }
2266
2267     /* Fill the surface of the smaller regular texture with red */
2268     if (surf_tex32 && surf_temp32) {
2269         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2270         fill_surface(surf_temp32, 0xffff0000);
2271         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2272         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2273     }
2274
2275     /* texture ==> offscreenplain, scaling (should fail) */
2276     if(surf_tex32 && surf_offscreen64) {
2277         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2278         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2279     }
2280
2281     /* texture ==> rendertarget texture, scaling */
2282     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2283         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2284         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2285
2286         /* We can't lock rendertarget textures, so copy to our temp surface first */
2287         if (hr == D3D_OK) {
2288             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2289             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2290         }
2291
2292         if (hr == D3D_OK) {
2293             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2294             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2295         }
2296     }
2297
2298     /* texture ==> rendertarget surface, scaling */
2299     if(surf_tex32 && surf_rt_dest64) {
2300         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2301         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2302
2303         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2304         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2305     }
2306
2307     /* texture ==> texture, scaling (should fail) */
2308     if(surf_tex32 && surf_tex_dest64) {
2309         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2310         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2311     }
2312
2313     /*****************************************************************
2314      * Tests for when the source parameter is a rendertarget texture *
2315      *****************************************************************/
2316
2317     /* Fill the surface of the rendertarget texture with white */
2318     if (surf_tex_rt64 && surf_temp64) {
2319         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2320         fill_surface(surf_temp64, 0xffffffff);
2321         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2322         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2323     }
2324
2325     /* rendertarget texture ==> offscreenplain, same size */
2326     if(surf_tex_rt64 && surf_offscreen64) {
2327         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2328         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2329     }
2330
2331     /* rendertarget texture ==> rendertarget texture, same size */
2332     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2333         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2334         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2335
2336         /* We can't lock rendertarget textures, so copy to our temp surface first */
2337         if (hr == D3D_OK) {
2338             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2339             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2340         }
2341
2342         if (hr == D3D_OK) {
2343             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2344             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2345         }
2346     }
2347
2348     /* rendertarget texture ==> rendertarget surface, same size */
2349     if(surf_tex_rt64 && surf_rt_dest64) {
2350         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2351         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2352
2353         if (hr == D3D_OK) {
2354             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2355             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2356         }
2357     }
2358
2359     /* rendertarget texture ==> texture, same size (should fail) */
2360     if(surf_tex_rt64 && surf_tex_dest64) {
2361         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2362         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2363     }
2364
2365     /* Fill the surface of the smaller rendertarget texture with red */
2366     if (surf_tex_rt32 && surf_temp32) {
2367         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2368         fill_surface(surf_temp32, 0xffff0000);
2369         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2370         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2371     }
2372
2373     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2374     if(surf_tex_rt32 && surf_offscreen64) {
2375         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2376         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2377     }
2378
2379     /* rendertarget texture ==> rendertarget texture, scaling */
2380     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2381         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2382         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2383
2384         /* We can't lock rendertarget textures, so copy to our temp surface first */
2385         if (hr == D3D_OK) {
2386             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2387             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2388         }
2389
2390         if (hr == D3D_OK) {
2391             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2392             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2393         }
2394     }
2395
2396     /* rendertarget texture ==> rendertarget surface, scaling */
2397     if(surf_tex_rt32 && surf_rt_dest64) {
2398         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2399         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2400
2401         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2402         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2403     }
2404
2405     /* rendertarget texture ==> texture, scaling (should fail) */
2406     if(surf_tex_rt32 && surf_tex_dest64) {
2407         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2408         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2409     }
2410
2411     /*****************************************************************
2412      * Tests for when the source parameter is a rendertarget surface *
2413      *****************************************************************/
2414
2415     /* Fill the surface of the rendertarget surface with black */
2416     if (surf_rt64)
2417         fill_surface(surf_rt64, 0xff000000);
2418
2419     /* rendertarget texture ==> offscreenplain, same size */
2420     if(surf_rt64 && surf_offscreen64) {
2421         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2422         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2423     }
2424
2425     /* rendertarget surface ==> rendertarget texture, same size */
2426     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2427         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2428         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2429
2430         /* We can't lock rendertarget textures, so copy to our temp surface first */
2431         if (hr == D3D_OK) {
2432             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2433             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2434         }
2435
2436         if (hr == D3D_OK) {
2437             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2438             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2439         }
2440     }
2441
2442     /* rendertarget surface ==> rendertarget surface, same size */
2443     if(surf_rt64 && surf_rt_dest64) {
2444         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2445         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2446
2447         if (hr == D3D_OK) {
2448             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2449             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2450         }
2451     }
2452
2453     /* rendertarget surface ==> texture, same size (should fail) */
2454     if(surf_rt64 && surf_tex_dest64) {
2455         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2456         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2457     }
2458
2459     /* Fill the surface of the smaller rendertarget texture with red */
2460     if (surf_rt32)
2461         fill_surface(surf_rt32, 0xffff0000);
2462
2463     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2464     if(surf_rt32 && surf_offscreen64) {
2465         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2466         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2467     }
2468
2469     /* rendertarget surface ==> rendertarget texture, scaling */
2470     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2471         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2472         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2473
2474         /* We can't lock rendertarget textures, so copy to our temp surface first */
2475         if (hr == D3D_OK) {
2476             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2477             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2478         }
2479
2480         if (hr == D3D_OK) {
2481             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2482             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2483         }
2484     }
2485
2486     /* rendertarget surface ==> rendertarget surface, scaling */
2487     if(surf_rt32 && surf_rt_dest64) {
2488         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2489         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2490
2491         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2492         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2493     }
2494
2495     /* rendertarget surface ==> texture, scaling (should fail) */
2496     if(surf_rt32 && surf_tex_dest64) {
2497         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2498         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2499     }
2500
2501     /* TODO: Test when source and destination RECT parameters are given... */
2502     /* TODO: Test format conversions */
2503
2504
2505 out:
2506     /* Clean up */
2507     if (surf_rt32)
2508         IDirect3DSurface9_Release(surf_rt32);
2509     if (surf_rt64)
2510         IDirect3DSurface9_Release(surf_rt64);
2511     if (surf_rt_dest64)
2512         IDirect3DSurface9_Release(surf_rt_dest64);
2513     if (surf_temp32)
2514         IDirect3DSurface9_Release(surf_temp32);
2515     if (surf_temp64)
2516         IDirect3DSurface9_Release(surf_temp64);
2517     if (surf_offscreen32)
2518         IDirect3DSurface9_Release(surf_offscreen32);
2519     if (surf_offscreen64)
2520         IDirect3DSurface9_Release(surf_offscreen64);
2521     if (surf_offscreen_dest64)
2522         IDirect3DSurface9_Release(surf_offscreen_dest64);
2523
2524     if (tex_rt32) {
2525         if (surf_tex_rt32)
2526             IDirect3DSurface9_Release(surf_tex_rt32);
2527         IDirect3DTexture9_Release(tex_rt32);
2528     }
2529     if (tex_rt64) {
2530         if (surf_tex_rt64)
2531             IDirect3DSurface9_Release(surf_tex_rt64);
2532         IDirect3DTexture9_Release(tex_rt64);
2533     }
2534     if (tex_rt_dest64) {
2535         if (surf_tex_rt_dest64)
2536             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2537         IDirect3DTexture9_Release(tex_rt_dest64);
2538     }
2539     if (tex32) {
2540         if (surf_tex32)
2541             IDirect3DSurface9_Release(surf_tex32);
2542         IDirect3DTexture9_Release(tex32);
2543     }
2544     if (tex64) {
2545         if (surf_tex64)
2546             IDirect3DSurface9_Release(surf_tex64);
2547         IDirect3DTexture9_Release(tex64);
2548     }
2549     if (tex_dest64) {
2550         if (surf_tex_dest64)
2551             IDirect3DSurface9_Release(surf_tex_dest64);
2552         IDirect3DTexture9_Release(tex_dest64);
2553     }
2554
2555     if (orig_rt) {
2556         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2557         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2558         IDirect3DSurface9_Release(orig_rt);
2559     }
2560 }
2561
2562 static void maxmip_test(IDirect3DDevice9 *device)
2563 {
2564     IDirect3DTexture9 *texture = NULL;
2565     IDirect3DSurface9 *surface = NULL;
2566     HRESULT hr;
2567     DWORD color;
2568     const float quads[] = {
2569         -1.0,   -1.0,   0.0,    0.0,    0.0,
2570         -1.0,    0.0,   0.0,    0.0,    1.0,
2571          0.0,   -1.0,   0.0,    1.0,    0.0,
2572          0.0,    0.0,   0.0,    1.0,    1.0,
2573
2574          0.0,   -1.0,   0.0,    0.0,    0.0,
2575          0.0,    0.0,   0.0,    0.0,    1.0,
2576          1.0,   -1.0,   0.0,    1.0,    0.0,
2577          1.0,    0.0,   0.0,    1.0,    1.0,
2578
2579          0.0,    0.0,   0.0,    0.0,    0.0,
2580          0.0,    1.0,   0.0,    0.0,    1.0,
2581          1.0,    0.0,   0.0,    1.0,    0.0,
2582          1.0,    1.0,   0.0,    1.0,    1.0,
2583
2584         -1.0,    0.0,   0.0,    0.0,    0.0,
2585         -1.0,    1.0,   0.0,    0.0,    1.0,
2586          0.0,    0.0,   0.0,    1.0,    0.0,
2587          0.0,    1.0,   0.0,    1.0,    1.0,
2588     };
2589
2590     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2591     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2592
2593     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2594                                         &texture, NULL);
2595     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2596     if(!texture)
2597     {
2598         skip("Failed to create test texture\n");
2599         return;
2600     }
2601
2602     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2603     fill_surface(surface, 0xffff0000);
2604     IDirect3DSurface9_Release(surface);
2605     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2606     fill_surface(surface, 0xff00ff00);
2607     IDirect3DSurface9_Release(surface);
2608     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2609     fill_surface(surface, 0xff0000ff);
2610     IDirect3DSurface9_Release(surface);
2611
2612     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2613     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2614     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2615     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2616
2617     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2619
2620     hr = IDirect3DDevice9_BeginScene(device);
2621     if(SUCCEEDED(hr))
2622     {
2623         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2624         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2625         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2626         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2627
2628         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2629         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2630         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2631         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2632
2633         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2634         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2635         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2636         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2637
2638         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2639         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2641         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2642         hr = IDirect3DDevice9_EndScene(device);
2643     }
2644
2645     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2646     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2647     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2648     color = getPixelColor(device, 160, 360);
2649     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2650     color = getPixelColor(device, 160, 120);
2651     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2652     color = getPixelColor(device, 480, 120);
2653     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2654     color = getPixelColor(device, 480, 360);
2655     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2656
2657     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2658     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2659
2660     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2661     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2662
2663     hr = IDirect3DDevice9_BeginScene(device);
2664     if(SUCCEEDED(hr))
2665     {
2666         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2667         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2668         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2669         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2670
2671         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2672         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2673         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2674         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2675
2676         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2677         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2678         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2679         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2680
2681         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2682         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2683         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2684         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2685         hr = IDirect3DDevice9_EndScene(device);
2686     }
2687
2688     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2689     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2690     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2691     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2692
2693     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2694     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2695     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2696      * samples from the highest level in the texture(level 2)
2697      */
2698     color = getPixelColor(device, 160, 360);
2699     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2700     color = getPixelColor(device, 160, 120);
2701     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2702     color = getPixelColor(device, 480, 120);
2703     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2704     color = getPixelColor(device, 480, 360);
2705     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2706
2707     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2708     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2709     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2710     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2711     IDirect3DTexture9_Release(texture);
2712 }
2713
2714 static void release_buffer_test(IDirect3DDevice9 *device)
2715 {
2716     IDirect3DVertexBuffer9 *vb = NULL;
2717     IDirect3DIndexBuffer9 *ib = NULL;
2718     HRESULT hr;
2719     BYTE *data;
2720     long ref;
2721
2722     static const struct vertex quad[] = {
2723         {-1.0,      -1.0,       0.1,        0xffff0000},
2724         {-1.0,       1.0,       0.1,        0xffff0000},
2725         { 1.0,       1.0,       0.1,        0xffff0000},
2726
2727         {-1.0,      -1.0,       0.1,        0xff00ff00},
2728         {-1.0,       1.0,       0.1,        0xff00ff00},
2729         { 1.0,       1.0,       0.1,        0xff00ff00}
2730     };
2731     short indices[] = {3, 4, 5};
2732
2733     /* Index and vertex buffers should always be creatable */
2734     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2735                                               D3DPOOL_MANAGED, &vb, NULL);
2736     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2737     if(!vb) {
2738         skip("Failed to create a vertex buffer\n");
2739         return;
2740     }
2741     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2742     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2743     if(!ib) {
2744         skip("Failed to create an index buffer\n");
2745         return;
2746     }
2747
2748     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2749     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2750     memcpy(data, quad, sizeof(quad));
2751     hr = IDirect3DVertexBuffer9_Unlock(vb);
2752     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2753
2754     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2755     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2756     memcpy(data, indices, sizeof(indices));
2757     hr = IDirect3DIndexBuffer9_Unlock(ib);
2758     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2759
2760     hr = IDirect3DDevice9_SetIndices(device, ib);
2761     ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2762     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2763     ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2764     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2765     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2766
2767     /* Now destroy the bound index buffer and draw again */
2768     ref = IDirect3DIndexBuffer9_Release(ib);
2769     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2770
2771     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2772     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2773
2774     hr = IDirect3DDevice9_BeginScene(device);
2775     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2776     if(SUCCEEDED(hr))
2777     {
2778         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2779          * making assumptions about the indices or vertices
2780          */
2781         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2782         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2783         hr = IDirect3DDevice9_EndScene(device);
2784         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2785     }
2786
2787     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2788     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2789
2790     hr = IDirect3DDevice9_SetIndices(device, NULL);
2791     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2792     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2793     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2794
2795     /* Index buffer was already destroyed as part of the test */
2796     IDirect3DVertexBuffer9_Release(vb);
2797 }
2798
2799 static void float_texture_test(IDirect3DDevice9 *device)
2800 {
2801     IDirect3D9 *d3d = NULL;
2802     HRESULT hr;
2803     IDirect3DTexture9 *texture = NULL;
2804     D3DLOCKED_RECT lr;
2805     float *data;
2806     DWORD color;
2807     float quad[] = {
2808         -1.0,      -1.0,       0.1,     0.0,    0.0,
2809         -1.0,       1.0,       0.1,     0.0,    1.0,
2810          1.0,      -1.0,       0.1,     1.0,    0.0,
2811          1.0,       1.0,       0.1,     1.0,    1.0,
2812     };
2813
2814     memset(&lr, 0, sizeof(lr));
2815     IDirect3DDevice9_GetDirect3D(device, &d3d);
2816     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2817                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2818         skip("D3DFMT_R32F textures not supported\n");
2819         goto out;
2820     }
2821
2822     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2823                                         D3DPOOL_MANAGED, &texture, NULL);
2824     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2825     if(!texture) {
2826         skip("Failed to create R32F texture\n");
2827         goto out;
2828     }
2829
2830     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2831     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2832     data = lr.pBits;
2833     *data = 0.0;
2834     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2835     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2836
2837     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2838     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2839
2840     hr = IDirect3DDevice9_BeginScene(device);
2841     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2842     if(SUCCEEDED(hr))
2843     {
2844         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2845         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2846
2847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2848         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2849
2850         hr = IDirect3DDevice9_EndScene(device);
2851         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2852     }
2853     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2854     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2855
2856     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2857     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2858
2859     color = getPixelColor(device, 240, 320);
2860     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2861
2862 out:
2863     if(texture) IDirect3DTexture9_Release(texture);
2864     IDirect3D9_Release(d3d);
2865 }
2866
2867 static void g16r16_texture_test(IDirect3DDevice9 *device)
2868 {
2869     IDirect3D9 *d3d = NULL;
2870     HRESULT hr;
2871     IDirect3DTexture9 *texture = NULL;
2872     D3DLOCKED_RECT lr;
2873     DWORD *data;
2874     DWORD color, red, green, blue;
2875     float quad[] = {
2876        -1.0,      -1.0,       0.1,     0.0,    0.0,
2877        -1.0,       1.0,       0.1,     0.0,    1.0,
2878         1.0,      -1.0,       0.1,     1.0,    0.0,
2879         1.0,       1.0,       0.1,     1.0,    1.0,
2880     };
2881
2882     memset(&lr, 0, sizeof(lr));
2883     IDirect3DDevice9_GetDirect3D(device, &d3d);
2884     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2885        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2886            skip("D3DFMT_G16R16 textures not supported\n");
2887            goto out;
2888     }
2889
2890     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2891                                         D3DPOOL_MANAGED, &texture, NULL);
2892     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2893     if(!texture) {
2894         skip("Failed to create D3DFMT_G16R16 texture\n");
2895         goto out;
2896     }
2897
2898     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2899     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2900     data = lr.pBits;
2901     *data = 0x0f00f000;
2902     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2903     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2904
2905     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2906     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2907
2908     hr = IDirect3DDevice9_BeginScene(device);
2909     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2910     if(SUCCEEDED(hr))
2911     {
2912         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2913         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2914
2915         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2916         ok(SUCCEEDED(hr), "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_SetTexture(device, 0, NULL);
2922     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2923
2924     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2925     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2926
2927     color = getPixelColor(device, 240, 320);
2928     red   = (color & 0x00ff0000) >> 16;
2929     green = (color & 0x0000ff00) >>  8;
2930     blue  = (color & 0x000000ff) >>  0;
2931     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2932        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2933
2934 out:
2935     if(texture) IDirect3DTexture9_Release(texture);
2936     IDirect3D9_Release(d3d);
2937 }
2938
2939 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2940 {
2941     HRESULT hr;
2942     IDirect3D9 *d3d;
2943     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2944     D3DCAPS9 caps;
2945     IDirect3DTexture9 *texture = NULL;
2946     IDirect3DVolumeTexture9 *volume = NULL;
2947     unsigned int x, y, z;
2948     D3DLOCKED_RECT lr;
2949     D3DLOCKED_BOX lb;
2950     DWORD color;
2951     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2952     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2953                            0.0, 1.0, 0.0, 0.0,
2954                            0.0, 0.0, 1.0, 0.0,
2955                            0.0, 0.0, 0.0, 1.0};
2956     static const D3DVERTEXELEMENT9 decl_elements[] = {
2957         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2958         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2959         D3DDECL_END()
2960     };
2961     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2962         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2963         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2964         D3DDECL_END()
2965     };
2966     static const D3DVERTEXELEMENT9 decl_elements3[] = {
2967         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2968         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2969         D3DDECL_END()
2970     };
2971     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2972                                                  0x00, 0xff, 0x00, 0x00,
2973                                                  0x00, 0x00, 0x00, 0x00,
2974                                                  0x00, 0x00, 0x00, 0x00};
2975
2976     memset(&lr, 0, sizeof(lr));
2977     memset(&lb, 0, sizeof(lb));
2978     IDirect3DDevice9_GetDirect3D(device, &d3d);
2979     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2980                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2981         fmt = D3DFMT_A16B16G16R16;
2982     }
2983     IDirect3D9_Release(d3d);
2984
2985     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2986     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2987     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
2988     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2989     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
2990     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2991     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
2992     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
2993     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2994     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
2995     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2996     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
2997     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2998     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
2999     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3000     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3001     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3002     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3003     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3004     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3006     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3007     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3008     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3009
3010     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3011     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3012     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3013                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3014     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3015     if(!texture) {
3016         skip("Failed to create the test texture\n");
3017         return;
3018     }
3019
3020     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3021      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3022      * 1.0 in red and green for the x and y coords
3023      */
3024     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3025     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3026     for(y = 0; y < caps.MaxTextureHeight; y++) {
3027         for(x = 0; x < caps.MaxTextureWidth; x++) {
3028             double r_f = (double) y / (double) caps.MaxTextureHeight;
3029             double g_f = (double) x / (double) caps.MaxTextureWidth;
3030             if(fmt == D3DFMT_A16B16G16R16) {
3031                 unsigned short r, g;
3032                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3033                 r = (unsigned short) (r_f * 65536.0);
3034                 g = (unsigned short) (g_f * 65536.0);
3035                 dst[0] = r;
3036                 dst[1] = g;
3037                 dst[2] = 0;
3038                 dst[3] = 65535;
3039             } else {
3040                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3041                 unsigned char r = (unsigned char) (r_f * 255.0);
3042                 unsigned char g = (unsigned char) (g_f * 255.0);
3043                 dst[0] = 0;
3044                 dst[1] = g;
3045                 dst[2] = r;
3046                 dst[3] = 255;
3047             }
3048         }
3049     }
3050     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3051     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3052     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3053     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3054
3055     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3056     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3057     hr = IDirect3DDevice9_BeginScene(device);
3058     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3059     if(SUCCEEDED(hr))
3060     {
3061         float quad1[] = {
3062             -1.0,      -1.0,       0.1,     1.0,    1.0,
3063             -1.0,       0.0,       0.1,     1.0,    1.0,
3064              0.0,      -1.0,       0.1,     1.0,    1.0,
3065              0.0,       0.0,       0.1,     1.0,    1.0,
3066         };
3067         float quad2[] = {
3068             -1.0,       0.0,       0.1,     1.0,    1.0,
3069             -1.0,       1.0,       0.1,     1.0,    1.0,
3070              0.0,       0.0,       0.1,     1.0,    1.0,
3071              0.0,       1.0,       0.1,     1.0,    1.0,
3072         };
3073         float quad3[] = {
3074              0.0,       0.0,       0.1,     0.5,    0.5,
3075              0.0,       1.0,       0.1,     0.5,    0.5,
3076              1.0,       0.0,       0.1,     0.5,    0.5,
3077              1.0,       1.0,       0.1,     0.5,    0.5,
3078         };
3079         float quad4[] = {
3080              320,       480,       0.1,     1.0,    0.0,    1.0,
3081              320,       240,       0.1,     1.0,    0.0,    1.0,
3082              640,       480,       0.1,     1.0,    0.0,    1.0,
3083              640,       240,       0.1,     1.0,    0.0,    1.0,
3084         };
3085         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3086                           0.0, 0.0, 0.0, 0.0,
3087                           0.0, 0.0, 0.0, 0.0,
3088                           0.0, 0.0, 0.0, 0.0};
3089
3090         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3091         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3092         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3093         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3094         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3095
3096         /* What happens with transforms enabled? */
3097         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3098         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3099         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3100         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3101
3102         /* What happens if 4 coords are used, but only 2 given ?*/
3103         mat[8] = 1.0;
3104         mat[13] = 1.0;
3105         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3106         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3107         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3108         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3109         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3110         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3111
3112         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3113          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3114          * due to the coords in the vertices. (turns out red, indeed)
3115          */
3116         memset(mat, 0, sizeof(mat));
3117         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3118         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3119         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3120         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3121         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3122         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3124         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3125
3126         hr = IDirect3DDevice9_EndScene(device);
3127         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3128     }
3129     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3130     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3131     color = getPixelColor(device, 160, 360);
3132     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3133     color = getPixelColor(device, 160, 120);
3134     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3135     color = getPixelColor(device, 480, 120);
3136     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3137     color = getPixelColor(device, 480, 360);
3138     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3139
3140     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3141     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3142
3143     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3144     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3145     hr = IDirect3DDevice9_BeginScene(device);
3146     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3147     if(SUCCEEDED(hr))
3148     {
3149         float quad1[] = {
3150             -1.0,      -1.0,       0.1,     0.8,    0.2,
3151             -1.0,       0.0,       0.1,     0.8,    0.2,
3152              0.0,      -1.0,       0.1,     0.8,    0.2,
3153              0.0,       0.0,       0.1,     0.8,    0.2,
3154         };
3155         float quad2[] = {
3156             -1.0,       0.0,       0.1,     0.5,    1.0,
3157             -1.0,       1.0,       0.1,     0.5,    1.0,
3158              0.0,       0.0,       0.1,     0.5,    1.0,
3159              0.0,       1.0,       0.1,     0.5,    1.0,
3160         };
3161         float quad3[] = {
3162              0.0,       0.0,       0.1,     0.5,    1.0,
3163              0.0,       1.0,       0.1,     0.5,    1.0,
3164              1.0,       0.0,       0.1,     0.5,    1.0,
3165              1.0,       1.0,       0.1,     0.5,    1.0,
3166         };
3167         float quad4[] = {
3168              0.0,      -1.0,       0.1,     0.8,    0.2,
3169              0.0,       0.0,       0.1,     0.8,    0.2,
3170              1.0,      -1.0,       0.1,     0.8,    0.2,
3171              1.0,       0.0,       0.1,     0.8,    0.2,
3172         };
3173         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3174                           0.0, 0.0, 0.0, 0.0,
3175                           0.0, 1.0, 0.0, 0.0,
3176                           0.0, 0.0, 0.0, 0.0};
3177
3178         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3179          */
3180         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3181         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3182         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3183         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3184
3185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3186         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3187
3188         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3189          * it behaves like COUNT2 because normal textures require 2 coords
3190          */
3191         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3192         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3193         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3194         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3195
3196         /* Just to be sure, the same as quad2 above */
3197         memset(mat, 0, sizeof(mat));
3198         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3199         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3200         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3201         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3203         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3204
3205         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3206          * used? And what happens to the first?
3207          */
3208         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3209         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3210         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3211         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3212
3213         hr = IDirect3DDevice9_EndScene(device);
3214         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3215     }
3216     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3217     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3218     color = getPixelColor(device, 160, 360);
3219     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3220     color = getPixelColor(device, 160, 120);
3221     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3222     color = getPixelColor(device, 480, 120);
3223     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3224        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3225     color = getPixelColor(device, 480, 360);
3226     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3227        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3228
3229     IDirect3DTexture9_Release(texture);
3230
3231     /* Test projected textures, without any fancy matrices */
3232     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3233     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3234     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3235     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3236     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3237     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3238     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3239     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3240
3241     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3242     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3243     for(x = 0; x < 4; x++) {
3244         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3245     }
3246     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3247     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3248     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3249     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3250
3251     hr = IDirect3DDevice9_BeginScene(device);
3252     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3253     if(SUCCEEDED(hr))
3254     {
3255         const float proj_quads[] = {
3256            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3257             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3258            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3259             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3260            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3261             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3262            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3263             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3264         };
3265
3266         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3267         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3268         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3269         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3270
3271         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3272         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3273         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3274         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3275
3276         hr = IDirect3DDevice9_EndScene(device);
3277         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3278     }
3279
3280     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3281     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3282     IDirect3DTexture9_Release(texture);
3283
3284     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3285     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3286     color = getPixelColor(device, 158, 118);
3287     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3288     color = getPixelColor(device, 162, 118);
3289     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3290     color = getPixelColor(device, 158, 122);
3291     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3292     color = getPixelColor(device, 162, 122);
3293     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3294
3295     color = getPixelColor(device, 158, 178);
3296     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3297     color = getPixelColor(device, 162, 178);
3298     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3299     color = getPixelColor(device, 158, 182);
3300     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3301     color = getPixelColor(device, 162, 182);
3302     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3303
3304     color = getPixelColor(device, 318, 118);
3305     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3306     color = getPixelColor(device, 322, 118);
3307     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3308     color = getPixelColor(device, 318, 122);
3309     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3310     color = getPixelColor(device, 322, 122);
3311     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3312
3313     color = getPixelColor(device, 318, 178);
3314     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3315     color = getPixelColor(device, 322, 178);
3316     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3317     color = getPixelColor(device, 318, 182);
3318     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3319     color = getPixelColor(device, 322, 182);
3320     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3321
3322     color = getPixelColor(device, 238, 298);
3323     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3324     color = getPixelColor(device, 242, 298);
3325     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3326     color = getPixelColor(device, 238, 302);
3327     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3328     color = getPixelColor(device, 242, 302);
3329     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3330
3331     color = getPixelColor(device, 238, 388);
3332     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3333     color = getPixelColor(device, 242, 388);
3334     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3335     color = getPixelColor(device, 238, 392);
3336     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3337     color = getPixelColor(device, 242, 392);
3338     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3339
3340     color = getPixelColor(device, 478, 298);
3341     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3342     color = getPixelColor(device, 482, 298);
3343     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3344     color = getPixelColor(device, 478, 302);
3345     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3346     color = getPixelColor(device, 482, 302);
3347     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3348
3349     color = getPixelColor(device, 478, 388);
3350     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3351     color = getPixelColor(device, 482, 388);
3352     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3353     color = getPixelColor(device, 478, 392);
3354     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3355     color = getPixelColor(device, 482, 392);
3356     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3357
3358     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3359     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3360     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3361      * Thus watch out if sampling from texels between 0 and 1.
3362      */
3363     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3364     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3365        "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3366     if(!volume) {
3367         skip("Failed to create a volume texture\n");
3368         goto out;
3369     }
3370
3371     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3372     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3373     for(z = 0; z < 32; z++) {
3374         for(y = 0; y < 32; y++) {
3375             for(x = 0; x < 32; x++) {
3376                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3377                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3378                 float r_f = (float) x / 31.0;
3379                 float g_f = (float) y / 31.0;
3380                 float b_f = (float) z / 31.0;
3381
3382                 if(fmt == D3DFMT_A16B16G16R16) {
3383                     unsigned short *mem_s = mem;
3384                     mem_s[0]  = r_f * 65535.0;
3385                     mem_s[1]  = g_f * 65535.0;
3386                     mem_s[2]  = b_f * 65535.0;
3387                     mem_s[3]  = 65535;
3388                 } else {
3389                     unsigned char *mem_c = mem;
3390                     mem_c[0]  = b_f * 255.0;
3391                     mem_c[1]  = g_f * 255.0;
3392                     mem_c[2]  = r_f * 255.0;
3393                     mem_c[3]  = 255;
3394                 }
3395             }
3396         }
3397     }
3398     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3399     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3400
3401     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3402     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3403
3404     hr = IDirect3DDevice9_BeginScene(device);
3405     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3406     if(SUCCEEDED(hr))
3407     {
3408         float quad1[] = {
3409             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3410             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3411              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3412              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3413         };
3414         float quad2[] = {
3415             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3416             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3417              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3418              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3419         };
3420         float quad3[] = {
3421              0.0,       0.0,       0.1,     0.0,    0.0,
3422              0.0,       1.0,       0.1,     0.0,    0.0,
3423              1.0,       0.0,       0.1,     0.0,    0.0,
3424              1.0,       1.0,       0.1,     0.0,    0.0
3425         };
3426         float quad4[] = {
3427              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3428              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3429              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3430              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3431         };
3432         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3433                          0.0, 0.0, 1.0, 0.0,
3434                          0.0, 1.0, 0.0, 0.0,
3435                          0.0, 0.0, 0.0, 1.0};
3436         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3437         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3438
3439         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3440          * values
3441          */
3442         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3443         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3444         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3445         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3447         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3448
3449         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3450          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3451          * otherwise the w will be missing(blue).
3452          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3453          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3454          */
3455         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3456         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3457         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3458         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3459
3460         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3461         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3462         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3463         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3464         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3465         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3466         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3467         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3468         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3469
3470         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3471          * disable. ATI extends it up to the amount of values needed for the volume texture
3472          */
3473         memset(mat, 0, sizeof(mat));
3474         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3475         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3476         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3477         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3478         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3479         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3480         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3481         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3482
3483         hr = IDirect3DDevice9_EndScene(device);
3484         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3485     }
3486     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3487     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3488
3489     color = getPixelColor(device, 160, 360);
3490     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3491     color = getPixelColor(device, 160, 120);
3492     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3493        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3494     color = getPixelColor(device, 480, 120);
3495     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3496     color = getPixelColor(device, 480, 360);
3497     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3498
3499     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3500     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3501     hr = IDirect3DDevice9_BeginScene(device);
3502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3503     if(SUCCEEDED(hr))
3504     {
3505         float quad1[] = {
3506             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3507             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3508              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3509              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3510         };
3511         float quad2[] = {
3512             -1.0,       0.0,       0.1,
3513             -1.0,       1.0,       0.1,
3514              0.0,       0.0,       0.1,
3515              0.0,       1.0,       0.1,
3516         };
3517         float quad3[] = {
3518              0.0,       0.0,       0.1,     1.0,
3519              0.0,       1.0,       0.1,     1.0,
3520              1.0,       0.0,       0.1,     1.0,
3521              1.0,       1.0,       0.1,     1.0
3522         };
3523         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3524                            0.0, 0.0, 0.0, 0.0,
3525                            0.0, 0.0, 0.0, 0.0,
3526                            0.0, 1.0, 0.0, 0.0};
3527         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3528                            1.0, 0.0, 0.0, 0.0,
3529                            0.0, 1.0, 0.0, 0.0,
3530                            0.0, 0.0, 1.0, 0.0};
3531         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3532         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3533
3534         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3535          */
3536         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3537         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3538         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3539         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3540         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3541         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3542
3543         /* None passed */
3544         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3545         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3546         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3547         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3548         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3549         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3550
3551         /* 4 used, 1 passed */
3552         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3553         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3554         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3555         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3556         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3557         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3558
3559         hr = IDirect3DDevice9_EndScene(device);
3560         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3561     }
3562     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3563     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3564     color = getPixelColor(device, 160, 360);
3565     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3566     color = getPixelColor(device, 160, 120);
3567     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3568     color = getPixelColor(device, 480, 120);
3569     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3570     /* Quad4: unused */
3571
3572     IDirect3DVolumeTexture9_Release(volume);
3573
3574     out:
3575     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3576     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3577     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3578     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3579     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3580     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3581     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3582     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3583     IDirect3DVertexDeclaration9_Release(decl);
3584     IDirect3DVertexDeclaration9_Release(decl2);
3585     IDirect3DVertexDeclaration9_Release(decl3);
3586 }
3587
3588 static void texdepth_test(IDirect3DDevice9 *device)
3589 {
3590     IDirect3DPixelShader9 *shader;
3591     HRESULT hr;
3592     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3593     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3594     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3595     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3596     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3597     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3598     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3599     DWORD shader_code[] = {
3600         0xffff0104,                                                                 /* ps_1_4               */
3601         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3602         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3603         0x0000fffd,                                                                 /* phase                */
3604         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3605         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3606         0x0000ffff                                                                  /* end                  */
3607     };
3608     DWORD color;
3609     float vertex[] = {
3610        -1.0,   -1.0,    0.0,
3611         1.0,   -1.0,    1.0,
3612        -1.0,    1.0,    0.0,
3613         1.0,    1.0,    1.0
3614     };
3615
3616     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3617     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3618
3619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3621     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3622     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3624     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3627     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3628
3629     /* Fill the depth buffer with a gradient */
3630     hr = IDirect3DDevice9_BeginScene(device);
3631     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3632     if(SUCCEEDED(hr))
3633     {
3634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3635         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3636         hr = IDirect3DDevice9_EndScene(device);
3637         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3638     }
3639
3640     /* Now perform the actual tests. Same geometry, but with the shader */
3641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3642     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3644     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3645     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3646     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3647
3648     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3649     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3650     hr = IDirect3DDevice9_BeginScene(device);
3651     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3652     if(SUCCEEDED(hr))
3653     {
3654         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3655         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3656
3657         hr = IDirect3DDevice9_EndScene(device);
3658         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3659     }
3660
3661     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3662     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3663     color = getPixelColor(device, 158, 240);
3664     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3665     color = getPixelColor(device, 162, 240);
3666     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3667
3668     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3669
3670     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3671     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3672     hr = IDirect3DDevice9_BeginScene(device);
3673     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3674     if(SUCCEEDED(hr))
3675     {
3676         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3677         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3678
3679         hr = IDirect3DDevice9_EndScene(device);
3680         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3681     }
3682
3683     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3684     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3685     color = getPixelColor(device, 318, 240);
3686     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3687     color = getPixelColor(device, 322, 240);
3688     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3689
3690     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3691
3692     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3693     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3694     hr = IDirect3DDevice9_BeginScene(device);
3695     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3696     if(SUCCEEDED(hr))
3697     {
3698         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3699         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3700
3701         hr = IDirect3DDevice9_EndScene(device);
3702         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3703     }
3704     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3705     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3706
3707     color = getPixelColor(device, 1, 240);
3708     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3709
3710     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3711
3712     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3713     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3714     hr = IDirect3DDevice9_BeginScene(device);
3715     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3716     if(SUCCEEDED(hr))
3717     {
3718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3719         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3720
3721         hr = IDirect3DDevice9_EndScene(device);
3722         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3723     }
3724     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3725     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3726     color = getPixelColor(device, 318, 240);
3727     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3728     color = getPixelColor(device, 322, 240);
3729     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3730
3731     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3732
3733     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3734     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3735     hr = IDirect3DDevice9_BeginScene(device);
3736     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3737     if(SUCCEEDED(hr))
3738     {
3739         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3740         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3741
3742         hr = IDirect3DDevice9_EndScene(device);
3743         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3744     }
3745     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3746     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3747
3748     color = getPixelColor(device, 1, 240);
3749     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3750
3751     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3752
3753     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3754     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3755     hr = IDirect3DDevice9_BeginScene(device);
3756     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3757     if(SUCCEEDED(hr))
3758     {
3759         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3760         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3761
3762         hr = IDirect3DDevice9_EndScene(device);
3763         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3764     }
3765     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3766     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3767
3768     color = getPixelColor(device, 638, 240);
3769     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3770
3771     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3772
3773     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3774     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3775     hr = IDirect3DDevice9_BeginScene(device);
3776     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3777     if(SUCCEEDED(hr))
3778     {
3779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3780         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3781
3782         hr = IDirect3DDevice9_EndScene(device);
3783         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3784     }
3785     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3786     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3787
3788     color = getPixelColor(device, 638, 240);
3789     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3790
3791     /* Cleanup */
3792     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3793     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3794     IDirect3DPixelShader9_Release(shader);
3795
3796     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3797     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3798     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3799     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3800 }
3801
3802 static void texkill_test(IDirect3DDevice9 *device)
3803 {
3804     IDirect3DPixelShader9 *shader;
3805     HRESULT hr;
3806     DWORD color;
3807
3808     const float vertex[] = {
3809     /*                          bottom  top    right    left */
3810         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3811          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3812         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3813          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3814     };
3815
3816     DWORD shader_code_11[] = {
3817     0xffff0101,                                                             /* ps_1_1                     */
3818     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3819     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3820     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3821     0x0000ffff                                                              /* end                        */
3822     };
3823     DWORD shader_code_20[] = {
3824     0xffff0200,                                                             /* ps_2_0                     */
3825     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3826     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3827     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3828     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3829     0x0000ffff                                                              /* end                        */
3830     };
3831
3832     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3833     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3834     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3835     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3836
3837     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3838     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3839     hr = IDirect3DDevice9_BeginScene(device);
3840     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3841     if(SUCCEEDED(hr))
3842     {
3843         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3844         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3846         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3847         hr = IDirect3DDevice9_EndScene(device);
3848         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3849     }
3850     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3851     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3852     color = getPixelColor(device, 63, 46);
3853     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3854     color = getPixelColor(device, 66, 46);
3855     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3856     color = getPixelColor(device, 63, 49);
3857     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3858     color = getPixelColor(device, 66, 49);
3859     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3860
3861     color = getPixelColor(device, 578, 46);
3862     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3863     color = getPixelColor(device, 575, 46);
3864     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3865     color = getPixelColor(device, 578, 49);
3866     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3867     color = getPixelColor(device, 575, 49);
3868     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3869
3870     color = getPixelColor(device, 63, 430);
3871     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3872     color = getPixelColor(device, 63, 433);
3873     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3874     color = getPixelColor(device, 66, 433);
3875     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3876     color = getPixelColor(device, 66, 430);
3877     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3878
3879     color = getPixelColor(device, 578, 430);
3880     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3881     color = getPixelColor(device, 578, 433);
3882     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3883     color = getPixelColor(device, 575, 433);
3884     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3885     color = getPixelColor(device, 575, 430);
3886     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3887
3888     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3889     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3890     IDirect3DPixelShader9_Release(shader);
3891
3892     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3893     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3894     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3895     if(FAILED(hr)) {
3896         skip("Failed to create 2.0 test shader, most likely not supported\n");
3897         return;
3898     }
3899
3900     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3901     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3902     hr = IDirect3DDevice9_BeginScene(device);
3903     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3904     if(SUCCEEDED(hr))
3905     {
3906         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3907         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3908         hr = IDirect3DDevice9_EndScene(device);
3909         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3910     }
3911     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3912
3913     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3914     color = getPixelColor(device, 63, 46);
3915     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3916     color = getPixelColor(device, 66, 46);
3917     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3918     color = getPixelColor(device, 63, 49);
3919     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3920     color = getPixelColor(device, 66, 49);
3921     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3922
3923     color = getPixelColor(device, 578, 46);
3924     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3925     color = getPixelColor(device, 575, 46);
3926     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3927     color = getPixelColor(device, 578, 49);
3928     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3929     color = getPixelColor(device, 575, 49);
3930     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3931
3932     color = getPixelColor(device, 63, 430);
3933     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3934     color = getPixelColor(device, 63, 433);
3935     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3936     color = getPixelColor(device, 66, 433);
3937     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3938     color = getPixelColor(device, 66, 430);
3939     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3940
3941     color = getPixelColor(device, 578, 430);
3942     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3943     color = getPixelColor(device, 578, 433);
3944     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3945     color = getPixelColor(device, 575, 433);
3946     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3947     color = getPixelColor(device, 575, 430);
3948     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3949
3950     /* Cleanup */
3951     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3952     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3953     IDirect3DPixelShader9_Release(shader);
3954 }
3955
3956 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3957 {
3958     IDirect3D9 *d3d9;
3959     HRESULT hr;
3960     IDirect3DTexture9 *texture;
3961     IDirect3DPixelShader9 *shader;
3962     IDirect3DPixelShader9 *shader2;
3963     D3DLOCKED_RECT lr;
3964     DWORD color;
3965     DWORD shader_code[] = {
3966         0xffff0101,                             /* ps_1_1       */
3967         0x00000042, 0xb00f0000,                 /* tex t0       */
3968         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3969         0x0000ffff                              /* end          */
3970     };
3971     DWORD shader_code2[] = {
3972         0xffff0101,                             /* ps_1_1       */
3973         0x00000042, 0xb00f0000,                 /* tex t0       */
3974         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3975         0x0000ffff                              /* end          */
3976     };
3977
3978     float quad[] = {
3979        -1.0,   -1.0,   0.1,     0.5,    0.5,
3980         1.0,   -1.0,   0.1,     0.5,    0.5,
3981        -1.0,    1.0,   0.1,     0.5,    0.5,
3982         1.0,    1.0,   0.1,     0.5,    0.5,
3983     };
3984
3985     memset(&lr, 0, sizeof(lr));
3986     IDirect3DDevice9_GetDirect3D(device, &d3d9);
3987     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3988                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
3989     IDirect3D9_Release(d3d9);
3990     if(FAILED(hr)) {
3991         skip("No D3DFMT_X8L8V8U8 support\n");
3992     };
3993
3994     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3995     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3996
3997     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
3998     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
3999     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4000     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4001     *((DWORD *) lr.pBits) = 0x11ca3141;
4002     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4003     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4004
4005     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4006     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4007     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4008     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4009
4010     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4011     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4012     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4013     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4014     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4015     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4016
4017     hr = IDirect3DDevice9_BeginScene(device);
4018     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4019     if(SUCCEEDED(hr))
4020     {
4021         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4022         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4023
4024         hr = IDirect3DDevice9_EndScene(device);
4025         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4026     }
4027     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4028     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4029     color = getPixelColor(device, 578, 430);
4030     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4031        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4032
4033     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4034     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4035     hr = IDirect3DDevice9_BeginScene(device);
4036     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4037     if(SUCCEEDED(hr))
4038     {
4039         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4040         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4041
4042         hr = IDirect3DDevice9_EndScene(device);
4043         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4044     }
4045     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4046     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4047     color = getPixelColor(device, 578, 430);
4048     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4049
4050     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4051     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4052     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4053     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4054     IDirect3DPixelShader9_Release(shader);
4055     IDirect3DPixelShader9_Release(shader2);
4056     IDirect3DTexture9_Release(texture);
4057 }
4058
4059 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4060 {
4061     HRESULT hr;
4062     IDirect3D9 *d3d;
4063     IDirect3DTexture9 *texture = NULL;
4064     IDirect3DSurface9 *surface;
4065     DWORD color;
4066     const RECT r1 = {256, 256, 512, 512};
4067     const RECT r2 = {512, 256, 768, 512};
4068     const RECT r3 = {256, 512, 512, 768};
4069     const RECT r4 = {512, 512, 768, 768};
4070     unsigned int x, y;
4071     D3DLOCKED_RECT lr;
4072     memset(&lr, 0, sizeof(lr));
4073
4074     IDirect3DDevice9_GetDirect3D(device, &d3d);
4075     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4076        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4077         skip("No autogenmipmap support\n");
4078         IDirect3D9_Release(d3d);
4079         return;
4080     }
4081     IDirect3D9_Release(d3d);
4082
4083     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4084     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4085
4086     /* Make the mipmap big, so that a smaller mipmap is used
4087      */
4088     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4089                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4090     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4091
4092     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4093     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4094     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4095     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4096     for(y = 0; y < 1024; y++) {
4097         for(x = 0; x < 1024; x++) {
4098             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4099             POINT pt;
4100
4101             pt.x = x;
4102             pt.y = y;
4103             if(PtInRect(&r1, pt)) {
4104                 *dst = 0xffff0000;
4105             } else if(PtInRect(&r2, pt)) {
4106                 *dst = 0xff00ff00;
4107             } else if(PtInRect(&r3, pt)) {
4108                 *dst = 0xff0000ff;
4109             } else if(PtInRect(&r4, pt)) {
4110                 *dst = 0xff000000;
4111             } else {
4112                 *dst = 0xffffffff;
4113             }
4114         }
4115     }
4116     hr = IDirect3DSurface9_UnlockRect(surface);
4117     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4118     IDirect3DSurface9_Release(surface);
4119
4120     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4121     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4122     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4123     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4124
4125     hr = IDirect3DDevice9_BeginScene(device);
4126     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4127     if(SUCCEEDED(hr)) {
4128         const float quad[] =  {
4129            -0.5,   -0.5,    0.1,    0.0,    0.0,
4130            -0.5,    0.5,    0.1,    0.0,    1.0,
4131             0.5,   -0.5,    0.1,    1.0,    0.0,
4132             0.5,    0.5,    0.1,    1.0,    1.0
4133         };
4134
4135         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4136         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4138         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4139         hr = IDirect3DDevice9_EndScene(device);
4140         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4141     }
4142     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4143     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4144     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4145     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4146     IDirect3DTexture9_Release(texture);
4147
4148     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4149     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4150     color = getPixelColor(device, 200, 200);
4151     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4152     color = getPixelColor(device, 280, 200);
4153     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4154     color = getPixelColor(device, 360, 200);
4155     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4156     color = getPixelColor(device, 440, 200);
4157     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4158     color = getPixelColor(device, 200, 270);
4159     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4160     color = getPixelColor(device, 280, 270);
4161     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4162     color = getPixelColor(device, 360, 270);
4163     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4164     color = getPixelColor(device, 440, 270);
4165     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4166 }
4167
4168 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4169 {
4170     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4171     IDirect3DVertexDeclaration9 *decl;
4172     HRESULT hr;
4173     DWORD color;
4174     DWORD shader_code_11[] =  {
4175         0xfffe0101,                                         /* vs_1_1           */
4176         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4177         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4178         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4179         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4180         0x0000ffff                                          /* end              */
4181     };
4182     DWORD shader_code_11_2[] =  {
4183         0xfffe0101,                                         /* vs_1_1           */
4184         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4185         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4186         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4187         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4188         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4189         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4190         0x0000ffff                                          /* end              */
4191     };
4192     DWORD shader_code_20[] =  {
4193         0xfffe0200,                                         /* vs_2_0           */
4194         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4195         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4196         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4197         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4198         0x0000ffff                                          /* end              */
4199     };
4200     DWORD shader_code_20_2[] =  {
4201         0xfffe0200,                                         /* vs_2_0           */
4202         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4203         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4204         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4205         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4206         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4207         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4208         0x0000ffff                                          /* end              */
4209     };
4210     static const D3DVERTEXELEMENT9 decl_elements[] = {
4211         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4212         D3DDECL_END()
4213     };
4214     float quad1[] = {
4215         -1.0,   -1.0,   0.1,
4216          0.0,   -1.0,   0.1,
4217         -1.0,    0.0,   0.1,
4218          0.0,    0.0,   0.1
4219     };
4220     float quad2[] = {
4221          0.0,   -1.0,   0.1,
4222          1.0,   -1.0,   0.1,
4223          0.0,    0.0,   0.1,
4224          1.0,    0.0,   0.1
4225     };
4226     float quad3[] = {
4227          0.0,    0.0,   0.1,
4228          1.0,    0.0,   0.1,
4229          0.0,    1.0,   0.1,
4230          1.0,    1.0,   0.1
4231     };
4232     float quad4[] = {
4233         -1.0,    0.0,   0.1,
4234          0.0,    0.0,   0.1,
4235         -1.0,    1.0,   0.1,
4236          0.0,    1.0,   0.1
4237     };
4238     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4239     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4240
4241     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4242     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4243
4244     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4245     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4246     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4247     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4248     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4249     if(FAILED(hr)) shader_20 = NULL;
4250     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4251     if(FAILED(hr)) shader_20_2 = NULL;
4252     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4253     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4254
4255     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4256     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4257     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4258     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4259     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4260     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4261
4262     hr = IDirect3DDevice9_BeginScene(device);
4263     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4264     if(SUCCEEDED(hr))
4265     {
4266         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4267         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4268         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4269         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4270
4271         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4272         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4273         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4274         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4275
4276         if(shader_20) {
4277             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4278             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4279             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4280             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4281         }
4282
4283         if(shader_20_2) {
4284             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4285             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4286             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4287             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4288         }
4289
4290         hr = IDirect3DDevice9_EndScene(device);
4291         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4292     }
4293     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4294     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4295
4296     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4297     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4298     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4299     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4300
4301     color = getPixelColor(device, 160, 360);
4302     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4303        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4304     color = getPixelColor(device, 480, 360);
4305     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4306        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4307     if(shader_20) {
4308         color = getPixelColor(device, 160, 120);
4309         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4310            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4311     }
4312     if(shader_20_2) {
4313         color = getPixelColor(device, 480, 120);
4314         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4315            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4316     }
4317
4318     IDirect3DVertexDeclaration9_Release(decl);
4319     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4320     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4321     IDirect3DVertexShader9_Release(shader_11_2);
4322     IDirect3DVertexShader9_Release(shader_11);
4323 }
4324
4325 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4326 {
4327     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4328     HRESULT hr;
4329     DWORD color;
4330     DWORD shader_code_11[] =  {
4331         0xffff0101,                                         /* ps_1_1           */
4332         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4333         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4334         0x0000ffff                                          /* end              */
4335     };
4336     DWORD shader_code_12[] =  {
4337         0xffff0102,                                         /* ps_1_2           */
4338         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4339         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4340         0x0000ffff                                          /* end              */
4341     };
4342     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4343      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4344      * During development of this test, 1.3 shaders were verified too
4345      */
4346     DWORD shader_code_14[] =  {
4347         0xffff0104,                                         /* ps_1_4           */
4348         /* Try to make one constant local. It gets clamped too, although the binary contains
4349          * the bigger numbers
4350          */
4351         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4352         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4353         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4354         0x0000ffff                                          /* end              */
4355     };
4356     DWORD shader_code_20[] =  {
4357         0xffff0200,                                         /* ps_2_0           */
4358         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4359         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4360         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4361         0x0000ffff                                          /* end              */
4362     };
4363     float quad1[] = {
4364         -1.0,   -1.0,   0.1,
4365          0.0,   -1.0,   0.1,
4366         -1.0,    0.0,   0.1,
4367          0.0,    0.0,   0.1
4368     };
4369     float quad2[] = {
4370          0.0,   -1.0,   0.1,
4371          1.0,   -1.0,   0.1,
4372          0.0,    0.0,   0.1,
4373          1.0,    0.0,   0.1
4374     };
4375     float quad3[] = {
4376          0.0,    0.0,   0.1,
4377          1.0,    0.0,   0.1,
4378          0.0,    1.0,   0.1,
4379          1.0,    1.0,   0.1
4380     };
4381     float quad4[] = {
4382         -1.0,    0.0,   0.1,
4383          0.0,    0.0,   0.1,
4384         -1.0,    1.0,   0.1,
4385          0.0,    1.0,   0.1
4386     };
4387     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4388     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4389
4390     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4391     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4392
4393     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4395     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4396     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4397     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4398     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4399     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4400     if(FAILED(hr)) shader_20 = NULL;
4401
4402     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4403     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4404     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4405     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4406     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4407     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4408
4409     hr = IDirect3DDevice9_BeginScene(device);
4410     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4411     if(SUCCEEDED(hr))
4412     {
4413         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4414         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4415         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4416         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4417
4418         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4419         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4420         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4421         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4422
4423         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4424         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4425         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4426         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4427
4428         if(shader_20) {
4429             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4430             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4431             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4432             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4433         }
4434
4435         hr = IDirect3DDevice9_EndScene(device);
4436         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4437     }
4438     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4439     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4440
4441     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4442     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4443
4444     color = getPixelColor(device, 160, 360);
4445     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4446        "quad 1 has color %08x, expected 0x00808000\n", color);
4447     color = getPixelColor(device, 480, 360);
4448     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4449        "quad 2 has color %08x, expected 0x00808000\n", color);
4450     color = getPixelColor(device, 480, 120);
4451     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4452        "quad 3 has color %08x, expected 0x00808000\n", color);
4453     if(shader_20) {
4454         color = getPixelColor(device, 160, 120);
4455         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4456            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4457     }
4458
4459     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4460     IDirect3DPixelShader9_Release(shader_14);
4461     IDirect3DPixelShader9_Release(shader_12);
4462     IDirect3DPixelShader9_Release(shader_11);
4463 }
4464
4465 static void dp2add_ps_test(IDirect3DDevice9 *device)
4466 {
4467     IDirect3DPixelShader9 *shader_dp2add = NULL;
4468     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4469     HRESULT hr;
4470     DWORD color;
4471
4472     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4473      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4474      * source tokens can be constants.  So, for this excercise, we move contents of c0 to
4475      * r0 first.
4476      * The result here for the r,g,b components should be rougly 0.5:
4477      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4478     static const DWORD shader_code_dp2add[] =  {
4479         0xffff0200,                                                             /* ps_2_0                       */
4480         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4481
4482         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4483         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4484
4485         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4486         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4487         0x0000ffff                                                              /* end                          */
4488     };
4489
4490     /* Test the _sat modifier, too.  Result here should be:
4491      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4492      *      _SAT: ==> 1.0
4493      *   ADD: (1.0 + -0.5) = 0.5
4494      */
4495     static const DWORD shader_code_dp2add_sat[] =  {
4496         0xffff0200,                                                             /* ps_2_0                           */
4497         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4498
4499         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4500         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4501         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4502
4503         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4504         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4505         0x0000ffff                                                              /* end                              */
4506     };
4507
4508     const float quad[] = {
4509         -1.0,   -1.0,   0.1,
4510          1.0,   -1.0,   0.1,
4511         -1.0,    1.0,   0.1,
4512          1.0,    1.0,   0.1
4513     };
4514
4515
4516     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4517     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4518
4519     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4520     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4521
4522     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4523     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4524
4525     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4526     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4527
4528     if (shader_dp2add) {
4529
4530         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4531         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4532
4533         hr = IDirect3DDevice9_BeginScene(device);
4534         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4535         if(SUCCEEDED(hr))
4536         {
4537             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4538             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4539
4540             hr = IDirect3DDevice9_EndScene(device);
4541             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4542         }
4543         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4544         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4545
4546         color = getPixelColor(device, 360, 240);
4547         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4548
4549         IDirect3DPixelShader9_Release(shader_dp2add);
4550     } else {
4551         skip("dp2add shader creation failed\n");
4552     }
4553
4554     if (shader_dp2add_sat) {
4555
4556         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4557         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4558
4559         hr = IDirect3DDevice9_BeginScene(device);
4560         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4561         if(SUCCEEDED(hr))
4562         {
4563             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4564             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4565
4566             hr = IDirect3DDevice9_EndScene(device);
4567             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4568         }
4569         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4570         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4571
4572         color = getPixelColor(device, 360, 240);
4573         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4574
4575         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4576     } else {
4577         skip("dp2add shader creation failed\n");
4578     }
4579
4580     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4581     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4582 }
4583
4584 static void cnd_test(IDirect3DDevice9 *device)
4585 {
4586     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4587     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4588     HRESULT hr;
4589     DWORD color;
4590     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4591      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4592      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4593      */
4594     DWORD shader_code_11[] =  {
4595         0xffff0101,                                                                 /* ps_1_1               */
4596         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4597         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4598         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4599         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4600         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4601         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4602         0x0000ffff                                                                  /* end                  */
4603     };
4604     DWORD shader_code_12[] =  {
4605         0xffff0102,                                                                 /* ps_1_2               */
4606         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4607         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4608         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4609         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4610         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4611         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4612         0x0000ffff                                                                  /* end                  */
4613     };
4614     DWORD shader_code_13[] =  {
4615         0xffff0103,                                                                 /* ps_1_3               */
4616         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4617         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4618         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4619         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4620         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4621         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4622         0x0000ffff                                                                  /* end                  */
4623     };
4624     DWORD shader_code_14[] =  {
4625         0xffff0104,                                                                 /* ps_1_3               */
4626         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4627         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4628         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4629         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4630         0x0000ffff                                                                  /* end                  */
4631     };
4632
4633     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4634      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4635      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4636      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4637      * native CreatePixelShader returns an error.
4638      *
4639      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4640      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4641      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4642      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4643      */
4644     DWORD shader_code_11_coissue[] =  {
4645         0xffff0101,                                                             /* ps_1_1                   */
4646         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4647         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4648         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4649         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4650         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4651         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4652         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4653         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4654         /* 0x40000000 = D3DSI_COISSUE */
4655         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4656         0x0000ffff                                                              /* end                      */
4657     };
4658     DWORD shader_code_12_coissue[] =  {
4659         0xffff0102,                                                             /* ps_1_2                   */
4660         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4661         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4662         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4663         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4664         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4665         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4666         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4667         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4668         /* 0x40000000 = D3DSI_COISSUE */
4669         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4670         0x0000ffff                                                              /* end                      */
4671     };
4672     DWORD shader_code_13_coissue[] =  {
4673         0xffff0103,                                                             /* ps_1_3                   */
4674         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4675         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4676         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4677         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4678         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4679         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4680         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4681         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4682         /* 0x40000000 = D3DSI_COISSUE */
4683         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4684         0x0000ffff                                                              /* end                      */
4685     };
4686     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4687      * compare against 0.5
4688      */
4689     DWORD shader_code_14_coissue[] =  {
4690         0xffff0104,                                                             /* ps_1_4                   */
4691         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4692         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4693         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4694         /* 0x40000000 = D3DSI_COISSUE */
4695         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4696         0x0000ffff                                                              /* end                      */
4697     };
4698     float quad1[] = {
4699         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4700          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4701         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4702          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4703     };
4704     float quad2[] = {
4705          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4706          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4707          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4708          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4709     };
4710     float quad3[] = {
4711          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4712          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4713          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4714          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4715     };
4716     float quad4[] = {
4717         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4718          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4719         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4720          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4721     };
4722     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4723     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4724     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4725     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4726
4727     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4728     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4729
4730     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4731     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4732     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4733     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4734     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4735     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4736     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4737     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4738     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4739     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4740     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4741     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4742     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4743     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4744     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4746
4747     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4748     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4749     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4750     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4751     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4752     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4753
4754     hr = IDirect3DDevice9_BeginScene(device);
4755     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4756     if(SUCCEEDED(hr))
4757     {
4758         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4759         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4760         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4761         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4762
4763         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4764         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4766         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4767
4768         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4769         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4771         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4772
4773         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4774         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4776         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4777
4778         hr = IDirect3DDevice9_EndScene(device);
4779         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4780     }
4781     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4782     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4783
4784     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4785     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4786
4787     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4788     color = getPixelColor(device, 158, 118);
4789     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4790     color = getPixelColor(device, 162, 118);
4791     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4792     color = getPixelColor(device, 158, 122);
4793     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4794     color = getPixelColor(device, 162, 122);
4795     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4796
4797     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4798     color = getPixelColor(device, 158, 358);
4799     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4800     color = getPixelColor(device, 162, 358);
4801     ok(color == 0x00000000, "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4802     color = getPixelColor(device, 158, 362);
4803     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4804     color = getPixelColor(device, 162, 362);
4805     ok(color == 0x00000000, "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4806
4807     /* 1.2 shader */
4808     color = getPixelColor(device, 478, 358);
4809     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4810     color = getPixelColor(device, 482, 358);
4811     ok(color == 0x00000000, "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4812     color = getPixelColor(device, 478, 362);
4813     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4814     color = getPixelColor(device, 482, 362);
4815     ok(color == 0x00000000, "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4816
4817     /* 1.3 shader */
4818     color = getPixelColor(device, 478, 118);
4819     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4820     color = getPixelColor(device, 482, 118);
4821     ok(color == 0x00000000, "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4822     color = getPixelColor(device, 478, 122);
4823     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4824     color = getPixelColor(device, 482, 122);
4825     ok(color == 0x00000000, "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4826
4827     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4828     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4829     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4830     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4831     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4832     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4833
4834     hr = IDirect3DDevice9_BeginScene(device);
4835     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4836     if(SUCCEEDED(hr))
4837     {
4838         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4839         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4840         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4841         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4842
4843         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4844         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4846         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4847
4848         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4849         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4850         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4851         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4852
4853         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4854         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4855         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4856         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4857
4858         hr = IDirect3DDevice9_EndScene(device);
4859         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4860     }
4861     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4862     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4863
4864     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4865      * that we swapped the values in c1 and c2 to make the other tests return some color
4866      */
4867     color = getPixelColor(device, 158, 118);
4868     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4869     color = getPixelColor(device, 162, 118);
4870     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4871     color = getPixelColor(device, 158, 122);
4872     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4873     color = getPixelColor(device, 162, 122);
4874     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4875
4876     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4877     color = getPixelColor(device, 158, 358);
4878     ok(color == 0x0000ff00, "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4879     color = getPixelColor(device, 162, 358);
4880     ok(color == 0x0000ff00, "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4881     color = getPixelColor(device, 158, 362);
4882     ok(color == 0x0000ff00, "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4883     color = getPixelColor(device, 162, 362);
4884     ok(color == 0x0000ff00, "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4885
4886     /* 1.2 shader */
4887     color = getPixelColor(device, 478, 358);
4888     ok(color == 0x0000ff00, "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4889     color = getPixelColor(device, 482, 358);
4890     ok(color == 0x0000ff00, "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4891     color = getPixelColor(device, 478, 362);
4892     ok(color == 0x0000ff00, "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4893     color = getPixelColor(device, 482, 362);
4894     ok(color == 0x0000ff00, "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4895
4896     /* 1.3 shader */
4897     color = getPixelColor(device, 478, 118);
4898     ok(color == 0x0000ff00, "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4899     color = getPixelColor(device, 482, 118);
4900     ok(color == 0x0000ff00, "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4901     color = getPixelColor(device, 478, 122);
4902     ok(color == 0x0000ff00, "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4903     color = getPixelColor(device, 482, 122);
4904     ok(color == 0x0000ff00, "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4905
4906     IDirect3DPixelShader9_Release(shader_14_coissue);
4907     IDirect3DPixelShader9_Release(shader_13_coissue);
4908     IDirect3DPixelShader9_Release(shader_12_coissue);
4909     IDirect3DPixelShader9_Release(shader_11_coissue);
4910     IDirect3DPixelShader9_Release(shader_14);
4911     IDirect3DPixelShader9_Release(shader_13);
4912     IDirect3DPixelShader9_Release(shader_12);
4913     IDirect3DPixelShader9_Release(shader_11);
4914 }
4915
4916 static void nested_loop_test(IDirect3DDevice9 *device) {
4917     const DWORD shader_code[] = {
4918         0xffff0300,                                                             /* ps_3_0               */
4919         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4920         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4921         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4922         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4923         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4924         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4925         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4926         0x0000001d,                                                             /* endloop              */
4927         0x0000001d,                                                             /* endloop              */
4928         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4929         0x0000ffff                                                              /* end                  */
4930     };
4931     IDirect3DPixelShader9 *shader;
4932     HRESULT hr;
4933     DWORD color;
4934     const float quad[] = {
4935         -1.0,   -1.0,   0.1,
4936          1.0,   -1.0,   0.1,
4937         -1.0,    1.0,   0.1,
4938          1.0,    1.0,   0.1
4939     };
4940
4941     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4942     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4943     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4944     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4945     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4946     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4947     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4948     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4949
4950     hr = IDirect3DDevice9_BeginScene(device);
4951     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4952     if(SUCCEEDED(hr))
4953     {
4954         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4955         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4956         hr = IDirect3DDevice9_EndScene(device);
4957         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4958     }
4959     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4960     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4961
4962     color = getPixelColor(device, 360, 240);
4963     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4964        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4965
4966     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4967     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4968     IDirect3DPixelShader9_Release(shader);
4969 }
4970
4971 struct varying_test_struct
4972 {
4973     const DWORD             *shader_code;
4974     IDirect3DPixelShader9   *shader;
4975     DWORD                   color, color_rhw;
4976     const char              *name;
4977     BOOL                    todo, todo_rhw;
4978 };
4979
4980 struct hugeVertex
4981 {
4982     float pos_x,        pos_y,      pos_z,      rhw;
4983     float weight_1,     weight_2,   weight_3,   weight_4;
4984     float index_1,      index_2,    index_3,    index_4;
4985     float normal_1,     normal_2,   normal_3,   normal_4;
4986     float fog_1,        fog_2,      fog_3,      fog_4;
4987     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
4988     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
4989     float binormal_1,   binormal_2, binormal_3, binormal_4;
4990     float depth_1,      depth_2,    depth_3,    depth_4;
4991     DWORD diffuse, specular;
4992 };
4993
4994 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
4995     /* dcl_position: fails to compile */
4996     const DWORD blendweight_code[] = {
4997         0xffff0300,                             /* ps_3_0                   */
4998         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
4999         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5000         0x0000ffff                              /* end                      */
5001     };
5002     const DWORD blendindices_code[] = {
5003         0xffff0300,                             /* ps_3_0                   */
5004         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5005         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5006         0x0000ffff                              /* end                      */
5007     };
5008     const DWORD normal_code[] = {
5009         0xffff0300,                             /* ps_3_0                   */
5010         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5011         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5012         0x0000ffff                              /* end                      */
5013     };
5014     /* psize: fails? */
5015     const DWORD texcoord0_code[] = {
5016         0xffff0300,                             /* ps_3_0                   */
5017         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5018         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5019         0x0000ffff                              /* end                      */
5020     };
5021     const DWORD tangent_code[] = {
5022         0xffff0300,                             /* ps_3_0                   */
5023         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5024         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5025         0x0000ffff                              /* end                      */
5026     };
5027     const DWORD binormal_code[] = {
5028         0xffff0300,                             /* ps_3_0                   */
5029         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5030         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5031         0x0000ffff                              /* end                      */
5032     };
5033     /* tessfactor: fails */
5034     /* positiont: fails */
5035     const DWORD color_code[] = {
5036         0xffff0300,                             /* ps_3_0                   */
5037         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5038         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5039         0x0000ffff                              /* end                      */
5040     };
5041     const DWORD fog_code[] = {
5042         0xffff0300,                             /* ps_3_0                   */
5043         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5044         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5045         0x0000ffff                              /* end                      */
5046     };
5047     const DWORD depth_code[] = {
5048         0xffff0300,                             /* ps_3_0                   */
5049         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5050         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5051         0x0000ffff                              /* end                      */
5052     };
5053     const DWORD specular_code[] = {
5054         0xffff0300,                             /* ps_3_0                   */
5055         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5056         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5057         0x0000ffff                              /* end                      */
5058     };
5059     /* sample: fails */
5060
5061     struct varying_test_struct tests[] = {
5062        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5063        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5064        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5065        /* Why does dx not forward the texcoord? */
5066        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5067        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5068        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5069        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5070        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5071        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5072        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5073     };
5074     /* Declare a monster vertex type :-) */
5075     static const D3DVERTEXELEMENT9 decl_elements[] = {
5076         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5077         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5078         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5079         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5080         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5081         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5082         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5083         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5084         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5085         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5086         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5087         D3DDECL_END()
5088     };
5089     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5090         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5091         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5092         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5093         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5094         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5095         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5096         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5097         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5098         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5099         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5100         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5101         D3DDECL_END()
5102     };
5103     struct hugeVertex data[4] = {
5104         {
5105             -1.0,   -1.0,   0.1,    1.0,
5106              0.1,    0.1,   0.1,    0.1,
5107              0.2,    0.2,   0.2,    0.2,
5108              0.3,    0.3,   0.3,    0.3,
5109              0.4,    0.4,   0.4,    0.4,
5110              0.50,   0.55,  0.55,   0.55,
5111              0.6,    0.6,   0.6,    0.7,
5112              0.7,    0.7,   0.7,    0.6,
5113              0.8,    0.8,   0.8,    0.8,
5114              0xe6e6e6e6, /* 0.9 * 256 */
5115              0x224488ff  /* Nothing special */
5116         },
5117         {
5118              1.0,   -1.0,   0.1,    1.0,
5119              0.1,    0.1,   0.1,    0.1,
5120              0.2,    0.2,   0.2,    0.2,
5121              0.3,    0.3,   0.3,    0.3,
5122              0.4,    0.4,   0.4,    0.4,
5123              0.50,   0.55,  0.55,   0.55,
5124              0.6,    0.6,   0.6,    0.7,
5125              0.7,    0.7,   0.7,    0.6,
5126              0.8,    0.8,   0.8,    0.8,
5127              0xe6e6e6e6, /* 0.9 * 256 */
5128              0x224488ff /* Nothing special */
5129         },
5130         {
5131             -1.0,    1.0,   0.1,    1.0,
5132              0.1,    0.1,   0.1,    0.1,
5133              0.2,    0.2,   0.2,    0.2,
5134              0.3,    0.3,   0.3,    0.3,
5135              0.4,    0.4,   0.4,    0.4,
5136              0.50,   0.55,  0.55,   0.55,
5137              0.6,    0.6,   0.6,    0.7,
5138              0.7,    0.7,   0.7,    0.6,
5139              0.8,    0.8,   0.8,    0.8,
5140              0xe6e6e6e6, /* 0.9 * 256 */
5141              0x224488ff /* Nothing special */
5142         },
5143         {
5144              1.0,    1.0,   0.1,    1.0,
5145              0.1,    0.1,   0.1,    0.1,
5146              0.2,    0.2,   0.2,    0.2,
5147              0.3,    0.3,   0.3,    0.3,
5148              0.4,    0.4,   0.4,    0.4,
5149              0.50,   0.55,  0.55,   0.55,
5150              0.6,    0.6,   0.6,    0.7,
5151              0.7,    0.7,   0.7,    0.6,
5152              0.8,    0.8,   0.8,    0.8,
5153              0xe6e6e6e6, /* 0.9 * 256 */
5154              0x224488ff /* Nothing special */
5155         },
5156     };
5157     struct hugeVertex data2[4];
5158     IDirect3DVertexDeclaration9 *decl;
5159     IDirect3DVertexDeclaration9 *decl2;
5160     HRESULT hr;
5161     unsigned int i;
5162     DWORD color, r, g, b, r_e, g_e, b_e;
5163
5164     memcpy(data2, data, sizeof(data2));
5165     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5166     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5167     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5168     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5169
5170     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5171     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5172     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5173     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5174     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5175     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5176
5177     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5178     {
5179         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5180         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5181            tests[i].name, DXGetErrorString9(hr));
5182     }
5183
5184     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5185     {
5186         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5187         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5188
5189         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5190         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5191
5192         hr = IDirect3DDevice9_BeginScene(device);
5193         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5194         if(SUCCEEDED(hr))
5195         {
5196             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5197             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5198             hr = IDirect3DDevice9_EndScene(device);
5199             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5200         }
5201         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5202         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5203
5204         color = getPixelColor(device, 360, 240);
5205         r = color & 0x00ff0000 >> 16;
5206         g = color & 0x0000ff00 >>  8;
5207         b = color & 0x000000ff;
5208         r_e = tests[i].color & 0x00ff0000 >> 16;
5209         g_e = tests[i].color & 0x0000ff00 >>  8;
5210         b_e = tests[i].color & 0x000000ff;
5211
5212         if(tests[i].todo) {
5213             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5214                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5215                          tests[i].name, color, tests[i].color);
5216         } else {
5217             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5218                "Test %s returned color 0x%08x, expected 0x%08x\n",
5219                tests[i].name, color, tests[i].color);
5220         }
5221     }
5222
5223     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5224     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5225     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5226     {
5227         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5228         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5229
5230         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5231         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5232
5233         hr = IDirect3DDevice9_BeginScene(device);
5234         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5235         if(SUCCEEDED(hr))
5236         {
5237             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5238             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5239             hr = IDirect3DDevice9_EndScene(device);
5240             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5241         }
5242         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5243         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5244
5245         color = getPixelColor(device, 360, 240);
5246         r = color & 0x00ff0000 >> 16;
5247         g = color & 0x0000ff00 >>  8;
5248         b = color & 0x000000ff;
5249         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5250         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5251         b_e = tests[i].color_rhw & 0x000000ff;
5252
5253         if(tests[i].todo_rhw) {
5254             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5255              * pipeline
5256              */
5257             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5258                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5259                          tests[i].name, color, tests[i].color_rhw);
5260         } else {
5261             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5262                "Test %s returned color 0x%08x, expected 0x%08x\n",
5263                tests[i].name, color, tests[i].color_rhw);
5264         }
5265     }
5266
5267     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5268     {
5269         IDirect3DPixelShader9_Release(tests[i].shader);
5270     }
5271
5272     IDirect3DVertexDeclaration9_Release(decl2);
5273     IDirect3DVertexDeclaration9_Release(decl);
5274 }
5275
5276 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5277     static const DWORD ps_code[] = {
5278     0xffff0300,                                                             /* ps_3_0                       */
5279     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5280     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5281     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5282     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5283     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5284     0x0200001f, 0x80000003, 0x900f0006,
5285     0x0200001f, 0x80000006, 0x900f0007,
5286     0x0200001f, 0x80000001, 0x900f0008,
5287     0x0200001f, 0x8000000c, 0x900f0009,
5288
5289     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5290     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5291     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5292     0x0000001d,                                                             /* endloop                      */
5293     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5294     0x0000ffff                                                              /* end                          */
5295     };
5296     static const DWORD vs_1_code[] = {
5297     0xfffe0101,                                                             /* vs_1_1                       */
5298     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5299     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5300     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5301     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5302     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5303     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5304     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5305     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5306     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5307     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5308     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5309     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5310     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5311     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5312     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5313     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5314     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5315     0x0000ffff
5316     };
5317     DWORD vs_2_code[] = {
5318     0xfffe0200,                                                             /* vs_2_0                       */
5319     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5320     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
5321     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0   */
5322     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0   */
5323     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5324     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5325     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5326     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5327     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5328     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5329     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5330     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5331     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5332     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5333     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5334     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5335     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5336     0x0000ffff                                                              /* end                          */
5337     };
5338     /* TODO: Define normal, tangent, blendweight and depth here */
5339     static const DWORD vs_3_code[] = {
5340     0xfffe0300,                                                             /* vs_3_0                       */
5341     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5342     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5343     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5344     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5345     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5346     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5347     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5348     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5349     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5350     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5351     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5352     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5353     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5354     0x0000ffff                                                              /* end                          */
5355     };
5356     float quad1[] =  {
5357         -1.0,   -1.0,   0.1,
5358          0.0,   -1.0,   0.1,
5359         -1.0,    0.0,   0.1,
5360          0.0,    0.0,   0.1
5361     };
5362     float quad2[] =  {
5363          0.0,   -1.0,   0.1,
5364          1.0,   -1.0,   0.1,
5365          0.0,    0.0,   0.1,
5366          1.0,    0.0,   0.1
5367     };
5368     float quad3[] =  {
5369         -1.0,    0.0,   0.1,
5370          0.0,    0.0,   0.1,
5371         -1.0,    1.0,   0.1,
5372          0.0,    1.0,   0.1
5373     };
5374
5375     HRESULT hr;
5376     DWORD color;
5377     IDirect3DPixelShader9 *pixelshader = NULL;
5378     IDirect3DVertexShader9 *vs_1_shader = NULL;
5379     IDirect3DVertexShader9 *vs_2_shader = NULL;
5380     IDirect3DVertexShader9 *vs_3_shader = NULL;
5381
5382     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5383
5384     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5385     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5386     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5387     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5388     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5389     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5390     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5391     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5392     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5393     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5394     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5395
5396     hr = IDirect3DDevice9_BeginScene(device);
5397     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5398     if(SUCCEEDED(hr))
5399     {
5400         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5401         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5402         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5403         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5404
5405         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5406         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5409
5410         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5411         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5412         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5413         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5414
5415         hr = IDirect3DDevice9_EndScene(device);
5416         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5417     }
5418     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5419     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5420
5421     color = getPixelColor(device, 160, 120);
5422     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5423        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5424        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
5425        "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5426     color = getPixelColor(device, 160, 360);
5427     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5428        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5429        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
5430        "vs_1_1 returned color 0x%08x, expected 0x00808080\n", color);
5431     color = getPixelColor(device, 480, 360);
5432     ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5433        (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5434        (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
5435        "vs_2_0 returned color 0x%08x, expected 0x00000000\n", color);
5436
5437     /* cleanup */
5438     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5439     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5440     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5441     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5442     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5443     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5444     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5445     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5446 }
5447
5448 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5449     static const DWORD vs_code[] = {
5450     0xfffe0300,                                                             /* vs_3_0                       */
5451     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5452     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5453     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5454     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5455     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5456     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5457     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5458     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5459     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5460     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5461     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5462     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5463     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5464
5465     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5466     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5467     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5468     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5469     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5470     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5471     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5472     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5473     0x0000ffff                                                              /* end                          */
5474     };
5475     static const DWORD ps_1_code[] = {
5476     0xffff0104,                                                             /* ps_1_4                       */
5477     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5478     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5479     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5480     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5481     0x0000ffff                                                              /* end                          */
5482     };
5483     static const DWORD ps_2_code[] = {
5484     0xffff0200,                                                             /* ps_2_0                       */
5485     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5486     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5487     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5488
5489     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5490     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5491     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5492     0x0000ffff                                                              /* end                          */
5493     };
5494     static const DWORD ps_3_code[] = {
5495     0xffff0300,                                                             /* ps_3_0                       */
5496     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5497     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5498     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5499
5500     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5501     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5502     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5503     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5504     0x0000ffff                                                              /* end                          */
5505     };
5506
5507     float quad1[] =  {
5508         -1.0,   -1.0,   0.1,
5509          0.0,   -1.0,   0.1,
5510         -1.0,    0.0,   0.1,
5511          0.0,    0.0,   0.1
5512     };
5513     float quad2[] =  {
5514          0.0,   -1.0,   0.1,
5515          1.0,   -1.0,   0.1,
5516          0.0,    0.0,   0.1,
5517          1.0,    0.0,   0.1
5518     };
5519     float quad3[] =  {
5520         -1.0,    0.0,   0.1,
5521          0.0,    0.0,   0.1,
5522         -1.0,    1.0,   0.1,
5523          0.0,    1.0,   0.1
5524     };
5525     float quad4[] =  {
5526          0.0,    0.0,   0.1,
5527          1.0,    0.0,   0.1,
5528          0.0,    1.0,   0.1,
5529          1.0,    1.0,   0.1
5530     };
5531
5532     HRESULT hr;
5533     DWORD color;
5534     IDirect3DVertexShader9 *vertexshader = NULL;
5535     IDirect3DPixelShader9 *ps_1_shader = NULL;
5536     IDirect3DPixelShader9 *ps_2_shader = NULL;
5537     IDirect3DPixelShader9 *ps_3_shader = NULL;
5538     IDirect3DTexture9 *texture = NULL;
5539     D3DLOCKED_RECT lr;
5540     unsigned int x, y;
5541
5542     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5543
5544     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5545     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5546     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5547     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5548     for(y = 0; y < 512; y++) {
5549         for(x = 0; x < 512; x++) {
5550             double r_f = (double) x / (double) 512;
5551             double g_f = (double) y / (double) 512;
5552             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5553             unsigned short r = (unsigned short) (r_f * 65535.0);
5554             unsigned short g = (unsigned short) (g_f * 65535.0);
5555             dst[0] = r;
5556             dst[1] = g;
5557             dst[2] = 0;
5558             dst[3] = 65535;
5559         }
5560     }
5561     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5562     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5563
5564     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5565     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5566     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5567     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5568     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5569     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5570     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5571     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5572     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5573     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5574     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5575
5576     hr = IDirect3DDevice9_BeginScene(device);
5577     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5578     if(SUCCEEDED(hr))
5579     {
5580         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5581         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5582         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5583         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5584
5585         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5586         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5587         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5588         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5589
5590         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5591         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5592         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5593         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5594
5595         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5596         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5597         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5598         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5599         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5600         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5601         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5602         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5604         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5605
5606         hr = IDirect3DDevice9_EndScene(device);
5607         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5608     }
5609     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5610     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5611
5612     color = getPixelColor(device, 160, 120);
5613     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5614        (color & 0x0000ff00) == 0x0000ff00 &&
5615        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5616        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5617     color = getPixelColor(device, 160, 360);
5618     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5619        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5620        (color & 0x000000ff) == 0x00000000,
5621        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5622     color = getPixelColor(device, 480, 360);
5623     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5624        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5625        (color & 0x000000ff) == 0x00000000,
5626        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5627     color = getPixelColor(device, 480, 160);
5628     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5629        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5630        (color & 0x000000ff) == 0x00000000,
5631        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5632
5633     /* cleanup */
5634     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5635     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5636     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5637     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5638     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5639     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5640     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5641     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5642     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5643     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5644     if(texture) IDirect3DTexture9_Release(texture);
5645 }
5646
5647 void test_compare_instructions(IDirect3DDevice9 *device)
5648 {
5649     DWORD shader_sge_vec_code[] = {
5650         0xfffe0101,                                         /* vs_1_1                   */
5651         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5652         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5653         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5654         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5655         0x0000ffff                                          /* end                      */
5656     };
5657     DWORD shader_slt_vec_code[] = {
5658         0xfffe0101,                                         /* vs_1_1                   */
5659         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5660         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5661         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5662         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5663         0x0000ffff                                          /* end                      */
5664     };
5665     DWORD shader_sge_scalar_code[] = {
5666         0xfffe0101,                                         /* vs_1_1                   */
5667         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5668         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5669         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5670         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5671         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5672         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5673         0x0000ffff                                          /* end                      */
5674     };
5675     DWORD shader_slt_scalar_code[] = {
5676         0xfffe0101,                                         /* vs_1_1                   */
5677         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5678         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5679         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5680         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5681         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5682         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5683         0x0000ffff                                          /* end                      */
5684     };
5685     IDirect3DVertexShader9 *shader_sge_vec;
5686     IDirect3DVertexShader9 *shader_slt_vec;
5687     IDirect3DVertexShader9 *shader_sge_scalar;
5688     IDirect3DVertexShader9 *shader_slt_scalar;
5689     HRESULT hr, color;
5690     float quad1[] =  {
5691         -1.0,   -1.0,   0.1,
5692          0.0,   -1.0,   0.1,
5693         -1.0,    0.0,   0.1,
5694          0.0,    0.0,   0.1
5695     };
5696     float quad2[] =  {
5697          0.0,   -1.0,   0.1,
5698          1.0,   -1.0,   0.1,
5699          0.0,    0.0,   0.1,
5700          1.0,    0.0,   0.1
5701     };
5702     float quad3[] =  {
5703         -1.0,    0.0,   0.1,
5704          0.0,    0.0,   0.1,
5705         -1.0,    1.0,   0.1,
5706          0.0,    1.0,   0.1
5707     };
5708     float quad4[] =  {
5709          0.0,    0.0,   0.1,
5710          1.0,    0.0,   0.1,
5711          0.0,    1.0,   0.1,
5712          1.0,    1.0,   0.1
5713     };
5714     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5715     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5716
5717     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5718
5719     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5720     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5721     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5722     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5723     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5724     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5725     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5726     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5727     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5728     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5729     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5730     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5731     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5732     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5733
5734     hr = IDirect3DDevice9_BeginScene(device);
5735     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5736     if(SUCCEEDED(hr))
5737     {
5738         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5739         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5740         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5741         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5742
5743         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5744         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5745         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5746         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5747
5748         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5749         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5750         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5751         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5752
5753         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5754         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5755
5756         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5757         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5758         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5759         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5760
5761         hr = IDirect3DDevice9_EndScene(device);
5762         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5763     }
5764
5765     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5766     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5767
5768     color = getPixelColor(device, 160, 360);
5769     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5770     color = getPixelColor(device, 480, 360);
5771     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5772     color = getPixelColor(device, 160, 120);
5773     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5774     color = getPixelColor(device, 480, 160);
5775     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5776
5777     IDirect3DVertexShader9_Release(shader_sge_vec);
5778     IDirect3DVertexShader9_Release(shader_slt_vec);
5779     IDirect3DVertexShader9_Release(shader_sge_scalar);
5780     IDirect3DVertexShader9_Release(shader_slt_scalar);
5781 }
5782
5783 void test_vshader_input(IDirect3DDevice9 *device)
5784 {
5785     DWORD swapped_shader_code_3[] = {
5786         0xfffe0300,                                         /* vs_3_0               */
5787         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5788         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5789         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5790         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5791         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5792         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5793         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5794         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5795         0x0000ffff                                          /* end                  */
5796     };
5797     DWORD swapped_shader_code_1[] = {
5798         0xfffe0101,                                         /* vs_1_1               */
5799         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5800         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5801         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5802         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5803         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5804         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5805         0x0000ffff                                          /* end                  */
5806     };
5807     DWORD swapped_shader_code_2[] = {
5808         0xfffe0200,                                         /* vs_2_0               */
5809         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5810         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5811         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5812         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5813         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5814         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5815         0x0000ffff                                          /* end                  */
5816     };
5817     DWORD texcoord_color_shader_code_3[] = {
5818         0xfffe0300,                                         /* vs_3_0               */
5819         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5820         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5821         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5822         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5823         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5824         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5825         0x0000ffff                                          /* end                  */
5826     };
5827     DWORD texcoord_color_shader_code_2[] = {
5828         0xfffe0200,                                         /* vs_2_0               */
5829         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5830         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5831         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5832         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5833         0x0000ffff                                          /* end                  */
5834     };
5835     DWORD texcoord_color_shader_code_1[] = {
5836         0xfffe0101,                                         /* vs_1_1               */
5837         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5838         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5839         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5840         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5841         0x0000ffff                                          /* end                  */
5842     };
5843     DWORD color_color_shader_code_3[] = {
5844         0xfffe0300,                                         /* vs_3_0               */
5845         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5846         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5847         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5848         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5849         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5850         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5851         0x0000ffff                                          /* end                  */
5852     };
5853     DWORD color_color_shader_code_2[] = {
5854         0xfffe0200,                                         /* vs_2_0               */
5855         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5856         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5857         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5858         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5859         0x0000ffff                                          /* end                  */
5860     };
5861     DWORD color_color_shader_code_1[] = {
5862         0xfffe0101,                                         /* vs_1_1               */
5863         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5864         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5865         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5866         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5867         0x0000ffff                                          /* end                  */
5868     };
5869     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5870     HRESULT hr;
5871     DWORD color, r, g, b;
5872     float quad1[] =  {
5873         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5874          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5875         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5876          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5877     };
5878     float quad2[] =  {
5879          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5880          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5881          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5882          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5883     };
5884     float quad3[] =  {
5885         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5886          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5887         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5888          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5889     };
5890     float quad4[] =  {
5891          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5892          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5893          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5894          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5895     };
5896     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5897         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5898         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5899         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5900         D3DDECL_END()
5901     };
5902     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5903         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5904         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5905         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5906         D3DDECL_END()
5907     };
5908     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5909         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5910         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5911         D3DDECL_END()
5912     };
5913     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5914         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5915         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5916         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5917         D3DDECL_END()
5918     };
5919     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5920         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5921         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5922         D3DDECL_END()
5923     };
5924     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5925         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5926         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5927         D3DDECL_END()
5928     };
5929     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5930         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5931         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5932         D3DDECL_END()
5933     };
5934     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5935         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5936         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5937         D3DDECL_END()
5938     };
5939     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5940     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5941     unsigned int i;
5942     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5943     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5944
5945     struct vertex quad1_color[] =  {
5946        {-1.0,   -1.0,   0.1,    0x00ff8040},
5947        { 0.0,   -1.0,   0.1,    0x00ff8040},
5948        {-1.0,    0.0,   0.1,    0x00ff8040},
5949        { 0.0,    0.0,   0.1,    0x00ff8040}
5950     };
5951     struct vertex quad2_color[] =  {
5952        { 0.0,   -1.0,   0.1,    0x00ff8040},
5953        { 1.0,   -1.0,   0.1,    0x00ff8040},
5954        { 0.0,    0.0,   0.1,    0x00ff8040},
5955        { 1.0,    0.0,   0.1,    0x00ff8040}
5956     };
5957     struct vertex quad3_color[] =  {
5958        {-1.0,    0.0,   0.1,    0x00ff8040},
5959        { 0.0,    0.0,   0.1,    0x00ff8040},
5960        {-1.0,    1.0,   0.1,    0x00ff8040},
5961        { 0.0,    1.0,   0.1,    0x00ff8040}
5962     };
5963     float quad4_color[] =  {
5964          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5965          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5966          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
5967          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
5968     };
5969
5970     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
5971     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5972     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
5973     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5974     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
5975     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5976     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
5977     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5978
5979     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
5980     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5981     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
5982     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5983     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
5984     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5985     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
5986     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5987
5988     for(i = 1; i <= 3; i++) {
5989         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5990         if(i == 3) {
5991             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
5992             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5993         } else if(i == 2){
5994             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
5995             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5996         } else if(i == 1) {
5997             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
5998             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5999         }
6000
6001         hr = IDirect3DDevice9_BeginScene(device);
6002         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6003         if(SUCCEEDED(hr))
6004         {
6005             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6006             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6007
6008             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6009             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6010             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6011             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6012
6013             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6014             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6015             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6016             if(i == 3 || i == 2) {
6017                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6018             } else if(i == 1) {
6019                 /* Succeeds or fails, depending on SW or HW vertex processing */
6020                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6021             }
6022
6023             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6024             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6025             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6026             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6027
6028             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6029             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6030             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6031             if(i == 3 || i == 2) {
6032                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6033             } else if(i == 1) {
6034                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6035             }
6036
6037             hr = IDirect3DDevice9_EndScene(device);
6038             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6039         }
6040
6041         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6042         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6043
6044         if(i == 3 || i == 2) {
6045             color = getPixelColor(device, 160, 360);
6046             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6047                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6048
6049             /* The last value of the read but undefined stream is used */
6050             color = getPixelColor(device, 480, 360);
6051             ok(color == 0x00FFFF00, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6052             color = getPixelColor(device, 160, 120);
6053             ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081,
6054                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6055
6056             color = getPixelColor(device, 480, 160);
6057             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6058         } else if(i == 1) {
6059             color = getPixelColor(device, 160, 360);
6060             ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6061                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6062             color = getPixelColor(device, 480, 360);
6063             /* Accept the clear color as well in this case, since SW VP returns an error */
6064             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6065             color = getPixelColor(device, 160, 120);
6066             ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6067                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6068             color = getPixelColor(device, 480, 160);
6069             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6070         }
6071
6072         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6073         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6074
6075         /* Now find out if the whole streams are re-read, or just the last active value for the
6076          * vertices is used.
6077          */
6078         hr = IDirect3DDevice9_BeginScene(device);
6079         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6080         if(SUCCEEDED(hr))
6081         {
6082             float quad1_modified[] =  {
6083                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6084                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6085                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6086                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6087             };
6088             float quad2_modified[] =  {
6089                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6090                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6091                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6092                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6093             };
6094
6095             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6096             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6097
6098             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6099             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6100             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6101             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6102
6103             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6104             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6105             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6106             if(i == 3 || i == 2) {
6107                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6108             } else if(i == 1) {
6109                 /* Succeeds or fails, depending on SW or HW vertex processing */
6110                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6111             }
6112
6113             hr = IDirect3DDevice9_EndScene(device);
6114             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6115         }
6116         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6117         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6118
6119         color = getPixelColor(device, 480, 360);
6120         /* vs_1_1 may fail, accept the clear color
6121          *
6122          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6123          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6124          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6125          * refrast's result.
6126          *
6127          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6128          */
6129         ok(color == 0x000000FF || color == 0x00808080,
6130            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF\n", color);
6131         color = getPixelColor(device, 160, 120);
6132
6133         IDirect3DDevice9_SetVertexShader(device, NULL);
6134         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6135
6136         IDirect3DVertexShader9_Release(swapped_shader);
6137     }
6138
6139     for(i = 1; i <= 3; i++) {
6140         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6141         if(i == 3) {
6142             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6143             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6144             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6145             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6146         } else if(i == 2){
6147             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6148             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6149             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6150             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6151         } else if(i == 1) {
6152             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6153             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6154             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6155             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6156         }
6157
6158         hr = IDirect3DDevice9_BeginScene(device);
6159         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6160         if(SUCCEEDED(hr))
6161         {
6162             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6163             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6164             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6165             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6166             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6167             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6168
6169             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6170             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6171
6172             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6173             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6174             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6175             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6176             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6177             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6178
6179             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6180             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6181             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6182             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6183             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6184             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6185
6186             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6187             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6188             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6189             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6190
6191             hr = IDirect3DDevice9_EndScene(device);
6192             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6193         }
6194         IDirect3DDevice9_SetVertexShader(device, NULL);
6195         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6196
6197         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6198         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6199
6200         color = getPixelColor(device, 160, 360);
6201         r = (color & 0x00ff0000) >> 16;
6202         g = (color & 0x0000ff00) >>  8;
6203         b = (color & 0x000000ff) >>  0;
6204         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6205            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6206         color = getPixelColor(device, 480, 360);
6207         r = (color & 0x00ff0000) >> 16;
6208         g = (color & 0x0000ff00) >>  8;
6209         b = (color & 0x000000ff) >>  0;
6210         ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6211            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6212         color = getPixelColor(device, 160, 120);
6213         r = (color & 0x00ff0000) >> 16;
6214         g = (color & 0x0000ff00) >>  8;
6215         b = (color & 0x000000ff) >>  0;
6216         ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6217            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6218         color = getPixelColor(device, 480, 160);
6219         r = (color & 0x00ff0000) >> 16;
6220         g = (color & 0x0000ff00) >>  8;
6221         b = (color & 0x000000ff) >>  0;
6222         ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6223            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6224
6225         IDirect3DVertexShader9_Release(texcoord_color_shader);
6226         IDirect3DVertexShader9_Release(color_color_shader);
6227     }
6228
6229     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6230     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6231     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6232     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6233
6234     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6235     IDirect3DVertexDeclaration9_Release(decl_color_color);
6236     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6237     IDirect3DVertexDeclaration9_Release(decl_color_float);
6238 }
6239
6240 static void srgbtexture_test(IDirect3DDevice9 *device)
6241 {
6242     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6243      * texture stage state to render a quad using that texture.  The resulting
6244      * color components should be 0x36 (~ 0.21), per this formula:
6245      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6246      * This is true where srgb_color > 0.04045.
6247      */
6248     IDirect3D9 *d3d = NULL;
6249     HRESULT hr;
6250     LPDIRECT3DTEXTURE9 texture = NULL;
6251     LPDIRECT3DSURFACE9 surface = NULL;
6252     D3DLOCKED_RECT lr;
6253     DWORD color;
6254     float quad[] = {
6255         -1.0,       1.0,       0.0,     0.0,    0.0,
6256          1.0,       1.0,       0.0,     1.0,    0.0,
6257         -1.0,      -1.0,       0.0,     0.0,    1.0,
6258          1.0,      -1.0,       0.0,     1.0,    1.0,
6259     };
6260
6261
6262     memset(&lr, 0, sizeof(lr));
6263     IDirect3DDevice9_GetDirect3D(device, &d3d);
6264     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6265                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6266                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6267         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6268         goto out;
6269     }
6270
6271     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6272                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6273                                         &texture, NULL);
6274     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6275     if(!texture) {
6276         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6277         goto out;
6278     }
6279     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6280     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6281
6282     fill_surface(surface, 0xff7f7f7f);
6283     IDirect3DSurface9_Release(surface);
6284
6285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6287     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6288     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6289
6290     hr = IDirect3DDevice9_BeginScene(device);
6291     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6292     if(SUCCEEDED(hr))
6293     {
6294         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6295         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6296
6297         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6298         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6299
6300
6301         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6302         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6303
6304         hr = IDirect3DDevice9_EndScene(device);
6305         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6306     }
6307
6308     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6309     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6310     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6311     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6312
6313     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6314     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6315
6316     color = getPixelColor(device, 320, 240);
6317     ok(color == 0x00363636, "srgb quad has color %08x, expected 0x00363636\n", color);
6318
6319 out:
6320     if(texture) IDirect3DTexture9_Release(texture);
6321     IDirect3D9_Release(d3d);
6322 }
6323
6324 static void shademode_test(IDirect3DDevice9 *device)
6325 {
6326     /* Render a quad and try all of the different fixed function shading models. */
6327     HRESULT hr;
6328     DWORD color0, color1;
6329     DWORD color0_gouraud = 0, color1_gouraud = 0;
6330     BYTE r, g, b;
6331     DWORD shademode = D3DSHADE_FLAT;
6332     DWORD primtype = D3DPT_TRIANGLESTRIP;
6333     LPVOID data = NULL;
6334     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6335     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6336     UINT i, j;
6337     struct vertex quad_strip[] =
6338     {
6339         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6340         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6341         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6342         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6343     };
6344     struct vertex quad_list[] =
6345     {
6346         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6347         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6348         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6349
6350         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6351         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6352         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6353     };
6354
6355     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6356                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6357     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6358     if (FAILED(hr)) goto bail;
6359
6360     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6361                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6362     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6363     if (FAILED(hr)) goto bail;
6364
6365     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6366     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6367
6368     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6369     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6370
6371     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6372     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6373     memcpy(data, quad_strip, sizeof(quad_strip));
6374     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6375     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6376
6377     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6378     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6379     memcpy(data, quad_list, sizeof(quad_list));
6380     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6381     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6382
6383     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6384      * the color fixups we have to do for FLAT shading will be dependent on that. */
6385     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6386     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6387
6388     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6389     for (j=0; j<2; j++) {
6390
6391         /* Inner loop just changes the D3DRS_SHADEMODE */
6392         for (i=0; i<3; i++) {
6393             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6394             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6395
6396             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6397             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6398
6399             hr = IDirect3DDevice9_BeginScene(device);
6400             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6401             if(SUCCEEDED(hr))
6402             {
6403                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6404                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6405
6406                 hr = IDirect3DDevice9_EndScene(device);
6407                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6408             }
6409
6410             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6411             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6412
6413             /* Sample two spots from the output */
6414             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6415             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6416             switch(shademode) {
6417                 case D3DSHADE_FLAT:
6418                     /* Should take the color of the first vertex of each triangle */
6419                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6420                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6421                     shademode = D3DSHADE_GOURAUD;
6422                     break;
6423                 case D3DSHADE_GOURAUD:
6424                     /* Should be an interpolated blend */
6425
6426                     r = (color0 & 0x00ff0000) >> 16;
6427                     g = (color0 & 0x0000ff00) >>  8;
6428                     b = (color0 & 0x000000ff);
6429                     ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6430                        "GOURAUD shading has color0 %08x, expected 0x000dca28\n", color0);
6431                     r = (color1 & 0x00ff0000) >> 16;
6432                     g = (color1 & 0x0000ff00) >>  8;
6433                     b = (color1 & 0x000000ff);
6434                     ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6435                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6436
6437                     color0_gouraud = color0;
6438                     color1_gouraud = color1;
6439
6440                     shademode = D3DSHADE_PHONG;
6441                     break;
6442                 case D3DSHADE_PHONG:
6443                     /* Should be the same as GOURAUD, since no hardware implements this */
6444                     r = (color0 & 0x00ff0000) >> 16;
6445                     g = (color0 & 0x0000ff00) >>  8;
6446                     b = (color0 & 0x000000ff);
6447                     ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6448                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6449                     r = (color1 & 0x00ff0000) >> 16;
6450                     g = (color1 & 0x0000ff00) >>  8;
6451                     b = (color1 & 0x000000ff);
6452                     ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6453                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6454
6455                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6456                             color0_gouraud, color0);
6457                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6458                             color1_gouraud, color1);
6459                     break;
6460             }
6461         }
6462         /* Now, do it all over again with a TRIANGLELIST */
6463         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6464         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6465         primtype = D3DPT_TRIANGLELIST;
6466         shademode = D3DSHADE_FLAT;
6467     }
6468
6469 bail:
6470     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6471     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6472     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6473     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6474
6475     if (vb_strip)
6476         IDirect3DVertexBuffer9_Release(vb_strip);
6477     if (vb_list)
6478         IDirect3DVertexBuffer9_Release(vb_list);
6479 }
6480
6481
6482 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6483 {
6484     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6485      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6486      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6487      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6488      * 0.73
6489      *
6490      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6491      * so use shaders for this task
6492      */
6493     IDirect3DPixelShader9 *pshader;
6494     IDirect3DVertexShader9 *vshader;
6495     IDirect3D9 *d3d;
6496     DWORD vshader_code[] = {
6497         0xfffe0101,                                                             /* vs_1_1                       */
6498         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6499         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6500         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6501         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6502         0x0000ffff                                                              /* end                          */
6503     };
6504     DWORD pshader_code[] = {
6505         0xffff0101,                                                             /* ps_1_1                       */
6506         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6507         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6508         0x0000ffff                                                              /* end                          */
6509     };
6510     const float quad[] = {
6511        -1.0,   -1.0,    0.1,
6512         1.0,   -1.0,    0.1,
6513        -1.0,    1.0,    0.1,
6514         1.0,    1.0,    0.1
6515     };
6516     HRESULT hr;
6517     DWORD color;
6518
6519     IDirect3DDevice9_GetDirect3D(device, &d3d);
6520     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6521                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6522                                     D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
6523         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6524         IDirect3D9_Release(d3d);
6525         return;
6526     }
6527     IDirect3D9_Release(d3d);
6528
6529     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6530     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6531
6532     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6533     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6534     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6535     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6536     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6537     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6538     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6539     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6540     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6541     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6542
6543     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6544     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6545     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6546     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6547     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6548     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6549     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6550     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6551     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6552     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6553
6554     hr = IDirect3DDevice9_BeginScene(device);
6555     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6556     if(SUCCEEDED(hr)) {
6557         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6558         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6559
6560         hr = IDirect3DDevice9_EndScene(device);
6561         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6562     }
6563
6564     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6565     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6566     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6567     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6568     IDirect3DPixelShader9_Release(pshader);
6569     IDirect3DVertexShader9_Release(vshader);
6570
6571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6572     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6574     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6575
6576     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6577     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6578     color = getPixelColor(device, 160, 360);
6579     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6580        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6581 }
6582
6583 static void alpha_test(IDirect3DDevice9 *device)
6584 {
6585     HRESULT hr;
6586     IDirect3DTexture9 *offscreenTexture;
6587     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6588     DWORD color, red, green, blue;
6589
6590     struct vertex quad1[] =
6591     {
6592         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6593         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6594         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6595         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6596     };
6597     struct vertex quad2[] =
6598     {
6599         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6600         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6601         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6602         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6603     };
6604     static const float composite_quad[][5] = {
6605         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6606         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6607         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6608         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6609     };
6610
6611     /* Clear the render target with alpha = 0.5 */
6612     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6613     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6614
6615     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6616     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6617
6618     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6619     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6620     if(!backbuffer) {
6621         goto out;
6622     }
6623
6624     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6625     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6626     if(!offscreen) {
6627         goto out;
6628     }
6629
6630     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6631     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6632
6633     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6634     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6635     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6636     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6637     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6638     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6639     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6640     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6642     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6643
6644     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6645     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6646     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6647
6648         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
6649          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
6650          * the input alpha
6651          *
6652          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
6653          * They give essentially ZERO and ONE blend factors
6654          */
6655         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6656         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6657         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6658         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6659         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6660         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6661
6662         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6663         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6664         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6665         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6666         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6667         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6668
6669         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
6670          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
6671          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
6672          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
6673          * vertices
6674          */
6675         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6676         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6677         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6678         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6679
6680         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6681         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6682         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6683         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6684         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6685         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6686
6687         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6688         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6689         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6690         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6691         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6692         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6693
6694         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6695         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6696
6697         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6698          * Disable alpha blending for the final composition
6699          */
6700         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6701         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6702         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6703         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6704
6705         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6706         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6707         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6708         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6709         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6710         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6711
6712         hr = IDirect3DDevice9_EndScene(device);
6713         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6714     }
6715
6716     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6717
6718     color = getPixelColor(device, 160, 360);
6719     red =   (color & 0x00ff0000) >> 16;
6720     green = (color & 0x0000ff00) >>  8;
6721     blue =  (color & 0x000000ff);
6722     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6723        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6724
6725     color = getPixelColor(device, 160, 120);
6726     red =   (color & 0x00ff0000) >> 16;
6727     green = (color & 0x0000ff00) >>  8;
6728     blue =  (color & 0x000000ff);
6729     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6730        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6731
6732     color = getPixelColor(device, 480, 360);
6733     red =   (color & 0x00ff0000) >> 16;
6734     green = (color & 0x0000ff00) >>  8;
6735     blue =  (color & 0x000000ff);
6736     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6737        "SRCALPHA on texture returned color %08x, expected bar\n", color);
6738
6739     color = getPixelColor(device, 480, 120);
6740     red =   (color & 0x00ff0000) >> 16;
6741     green = (color & 0x0000ff00) >>  8;
6742     blue =  (color & 0x000000ff);
6743     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6744        "DSTALPHA on texture returned color %08x, expected foo\n", color);
6745
6746     out:
6747     /* restore things */
6748     if(backbuffer) {
6749         IDirect3DSurface9_Release(backbuffer);
6750     }
6751     if(offscreenTexture) {
6752         IDirect3DTexture9_Release(offscreenTexture);
6753     }
6754     if(offscreen) {
6755         IDirect3DSurface9_Release(offscreen);
6756     }
6757 }
6758
6759 struct vertex_shortcolor {
6760     float x, y, z;
6761     unsigned short r, g, b, a;
6762 };
6763 struct vertex_floatcolor {
6764     float x, y, z;
6765     float r, g, b, a;
6766 };
6767
6768 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6769 {
6770     HRESULT hr;
6771     BOOL s_ok, ub_ok, f_ok;
6772     DWORD color, size, i;
6773     void *data;
6774     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6775         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6776         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6777         D3DDECL_END()
6778     };
6779     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6780         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6781         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6782         D3DDECL_END()
6783     };
6784     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6785         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6786         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6787         D3DDECL_END()
6788     };
6789     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6790         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6791         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6792         D3DDECL_END()
6793     };
6794     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6795         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6796         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6797         D3DDECL_END()
6798     };
6799     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6800         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6801         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6802         D3DDECL_END()
6803     };
6804     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6805         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6806         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6807         D3DDECL_END()
6808     };
6809     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6810     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6811     IDirect3DVertexBuffer9 *vb, *vb2;
6812     struct vertex quad1[] =                             /* D3DCOLOR */
6813     {
6814         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6815         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6816         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6817         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6818     };
6819     struct vertex quad2[] =                             /* UBYTE4N */
6820     {
6821         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6822         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6823         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6824         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6825     };
6826     struct vertex_shortcolor quad3[] =                  /* short */
6827     {
6828         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6829         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6830         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6831         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6832     };
6833     struct vertex_floatcolor quad4[] =
6834     {
6835         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6836         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6837         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6838         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6839     };
6840     DWORD colors[] = {
6841         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6842         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6843         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6844         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6845         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6846         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6847         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6848         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6849         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6850         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6851         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6852         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6853         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6854         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6855         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6856         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6857     };
6858     float quads[] = {
6859         -1.0,   -1.0,     0.1,
6860         -1.0,    0.0,     0.1,
6861          0.0,   -1.0,     0.1,
6862          0.0,    0.0,     0.1,
6863
6864          0.0,   -1.0,     0.1,
6865          0.0,    0.0,     0.1,
6866          1.0,   -1.0,     0.1,
6867          1.0,    0.0,     0.1,
6868
6869          0.0,    0.0,     0.1,
6870          0.0,    1.0,     0.1,
6871          1.0,    0.0,     0.1,
6872          1.0,    1.0,     0.1,
6873
6874         -1.0,    0.0,     0.1,
6875         -1.0,    1.0,     0.1,
6876          0.0,    0.0,     0.1,
6877          0.0,    1.0,     0.1
6878     };
6879     struct tvertex quad_transformed[] = {
6880        {  90,    110,     0.1,      2.0,        0x00ffff00},
6881        { 570,    110,     0.1,      2.0,        0x00ffff00},
6882        {  90,    300,     0.1,      2.0,        0x00ffff00},
6883        { 570,    300,     0.1,      2.0,        0x00ffff00}
6884     };
6885     D3DCAPS9 caps;
6886
6887     memset(&caps, 0, sizeof(caps));
6888     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6889     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6890
6891     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6892     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6893
6894     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6895     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6896     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6897     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6898     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6899     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6900     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6901         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6902         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6903         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6904         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6905     } else {
6906         trace("D3DDTCAPS_UBYTE4N not supported\n");
6907         dcl_ubyte_2 = NULL;
6908         dcl_ubyte = NULL;
6909     }
6910     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6911     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6912     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6913     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6914
6915     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6916     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6917                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6918     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6919
6920     hr = IDirect3DDevice9_BeginScene(device);
6921     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6922     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6923     if(SUCCEEDED(hr)) {
6924         if(dcl_color) {
6925             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6926             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6927             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6928             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6929         }
6930
6931         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6932          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6933          * using software vertex processing. Doh!
6934          */
6935         if(dcl_ubyte) {
6936             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6937             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6938             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6939             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6940             ub_ok = SUCCEEDED(hr);
6941         }
6942
6943         if(dcl_short) {
6944             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6945             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6946             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6947             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6948             s_ok = SUCCEEDED(hr);
6949         }
6950
6951         if(dcl_float) {
6952             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6953             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6954             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6955             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6956             f_ok = SUCCEEDED(hr);
6957         }
6958
6959         hr = IDirect3DDevice9_EndScene(device);
6960         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6961     }
6962
6963     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6964     if(dcl_short) {
6965         color = getPixelColor(device, 480, 360);
6966         ok(color == 0x000000ff || !s_ok,
6967            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6968     }
6969     if(dcl_ubyte) {
6970         color = getPixelColor(device, 160, 120);
6971         ok(color == 0x0000ffff || !ub_ok,
6972            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6973     }
6974     if(dcl_color) {
6975         color = getPixelColor(device, 160, 360);
6976         ok(color == 0x00ffff00,
6977            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6978     }
6979     if(dcl_float) {
6980         color = getPixelColor(device, 480, 120);
6981         ok(color == 0x00ff0000 || !f_ok,
6982            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
6983     }
6984
6985     /* The following test with vertex buffers doesn't serve to find out new information from windows.
6986      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
6987      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
6988      * whether the immediate mode code works
6989      */
6990     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6991     hr = IDirect3DDevice9_BeginScene(device);
6992     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6993     if(SUCCEEDED(hr)) {
6994         if(dcl_color) {
6995             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
6996             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6997             memcpy(data, quad1, sizeof(quad1));
6998             hr = IDirect3DVertexBuffer9_Unlock(vb);
6999             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7000             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7001             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7002             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7003             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7004             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7005             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7006         }
7007
7008         if(dcl_ubyte) {
7009             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7010             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7011             memcpy(data, quad2, sizeof(quad2));
7012             hr = IDirect3DVertexBuffer9_Unlock(vb);
7013             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7014             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7015             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7016             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7017             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7018             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7019             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7020                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7021             ub_ok = SUCCEEDED(hr);
7022         }
7023
7024         if(dcl_short) {
7025             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7026             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7027             memcpy(data, quad3, sizeof(quad3));
7028             hr = IDirect3DVertexBuffer9_Unlock(vb);
7029             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7030             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7031             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7032             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7033             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7034             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7035             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7036                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7037             s_ok = SUCCEEDED(hr);
7038         }
7039
7040         if(dcl_float) {
7041             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7042             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7043             memcpy(data, quad4, sizeof(quad4));
7044             hr = IDirect3DVertexBuffer9_Unlock(vb);
7045             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7046             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7047             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7048             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7049             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7050             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7051             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7052                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7053             f_ok = SUCCEEDED(hr);
7054         }
7055
7056         hr = IDirect3DDevice9_EndScene(device);
7057         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7058     }
7059
7060     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7061     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7062     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7063     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7064
7065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7066     if(dcl_short) {
7067         color = getPixelColor(device, 480, 360);
7068         ok(color == 0x000000ff || !s_ok,
7069            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7070     }
7071     if(dcl_ubyte) {
7072         color = getPixelColor(device, 160, 120);
7073         ok(color == 0x0000ffff || !ub_ok,
7074            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7075     }
7076     if(dcl_color) {
7077         color = getPixelColor(device, 160, 360);
7078         ok(color == 0x00ffff00,
7079            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7080     }
7081     if(dcl_float) {
7082         color = getPixelColor(device, 480, 120);
7083         ok(color == 0x00ff0000 || !f_ok,
7084            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7085     }
7086
7087     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7088     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7089
7090     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7091     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7092     memcpy(data, quad_transformed, sizeof(quad_transformed));
7093     hr = IDirect3DVertexBuffer9_Unlock(vb);
7094     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7095
7096     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7097     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7098
7099     hr = IDirect3DDevice9_BeginScene(device);
7100     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7101     if(SUCCEEDED(hr)) {
7102         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7103         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7104         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7105         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7106
7107         hr = IDirect3DDevice9_EndScene(device);
7108         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7109     }
7110
7111     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7112     color = getPixelColor(device, 88, 108);
7113     ok(color == 0x000000ff,
7114        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7115     color = getPixelColor(device, 92, 108);
7116     ok(color == 0x000000ff,
7117        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7118     color = getPixelColor(device, 88, 112);
7119     ok(color == 0x000000ff,
7120        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7121     color = getPixelColor(device, 92, 112);
7122     ok(color == 0x00ffff00,
7123        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7124
7125     color = getPixelColor(device, 568, 108);
7126     ok(color == 0x000000ff,
7127        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7128     color = getPixelColor(device, 572, 108);
7129     ok(color == 0x000000ff,
7130        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7131     color = getPixelColor(device, 568, 112);
7132     ok(color == 0x00ffff00,
7133        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7134     color = getPixelColor(device, 572, 112);
7135     ok(color == 0x000000ff,
7136        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7137
7138     color = getPixelColor(device, 88, 298);
7139     ok(color == 0x000000ff,
7140        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7141     color = getPixelColor(device, 92, 298);
7142     ok(color == 0x00ffff00,
7143        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7144     color = getPixelColor(device, 88, 302);
7145     ok(color == 0x000000ff,
7146        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7147     color = getPixelColor(device, 92, 302);
7148     ok(color == 0x000000ff,
7149        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7150
7151     color = getPixelColor(device, 568, 298);
7152     ok(color == 0x00ffff00,
7153        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7154     color = getPixelColor(device, 572, 298);
7155     ok(color == 0x000000ff,
7156        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7157     color = getPixelColor(device, 568, 302);
7158     ok(color == 0x000000ff,
7159        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7160     color = getPixelColor(device, 572, 302);
7161     ok(color == 0x000000ff,
7162        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7163
7164     /* This test is pointless without those two declarations: */
7165     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7166         skip("color-ubyte switching test declarations aren't supported\n");
7167         goto out;
7168     }
7169
7170     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7171     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7172     memcpy(data, quads, sizeof(quads));
7173     hr = IDirect3DVertexBuffer9_Unlock(vb);
7174     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7175     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7176                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7177     ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7178     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7179     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7180     memcpy(data, colors, sizeof(colors));
7181     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7182     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7183
7184     for(i = 0; i < 2; i++) {
7185         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7186         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7187
7188         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7189         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7190         if(i == 0) {
7191             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7192         } else {
7193             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7194         }
7195         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7196
7197         hr = IDirect3DDevice9_BeginScene(device);
7198         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7199         ub_ok = FALSE;
7200         if(SUCCEEDED(hr)) {
7201             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7202             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7203             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7204             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7205                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7206             ub_ok = SUCCEEDED(hr);
7207
7208             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7209             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7210             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7211             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7212
7213             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7214             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7215             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7216             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7217                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7218             ub_ok = (SUCCEEDED(hr) && ub_ok);
7219
7220             hr = IDirect3DDevice9_EndScene(device);
7221             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7222         }
7223
7224         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7225         if(i == 0) {
7226             color = getPixelColor(device, 480, 360);
7227             ok(color == 0x00ff0000,
7228                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7229             color = getPixelColor(device, 160, 120);
7230             ok(color == 0x00ffffff,
7231                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7232             color = getPixelColor(device, 160, 360);
7233             ok(color == 0x000000ff || !ub_ok,
7234                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7235             color = getPixelColor(device, 480, 120);
7236             ok(color == 0x000000ff || !ub_ok,
7237                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7238         } else {
7239             color = getPixelColor(device, 480, 360);
7240             ok(color == 0x000000ff,
7241                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7242             color = getPixelColor(device, 160, 120);
7243             ok(color == 0x00ffffff,
7244                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7245             color = getPixelColor(device, 160, 360);
7246             ok(color == 0x00ff0000 || !ub_ok,
7247                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7248             color = getPixelColor(device, 480, 120);
7249             ok(color == 0x00ff0000 || !ub_ok,
7250                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7251         }
7252     }
7253
7254     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7255     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7256     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7257     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7258     IDirect3DVertexBuffer9_Release(vb2);
7259
7260     out:
7261     IDirect3DVertexBuffer9_Release(vb);
7262     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7263     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7264     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7265     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7266     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7267     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7268     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7269 }
7270
7271 struct vertex_float16color {
7272     float x, y, z;
7273     DWORD c1, c2;
7274 };
7275
7276 static void test_vshader_float16(IDirect3DDevice9 *device)
7277 {
7278     HRESULT hr;
7279     DWORD color;
7280     void *data;
7281     static const D3DVERTEXELEMENT9 decl_elements[] = {
7282         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7283         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7284         D3DDECL_END()
7285     };
7286     IDirect3DVertexDeclaration9 *vdecl = NULL;
7287     IDirect3DVertexBuffer9 *buffer = NULL;
7288     IDirect3DVertexShader9 *shader;
7289     DWORD shader_code[] = {
7290         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7291         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7292         0x90e40001, 0x0000ffff
7293     };
7294     struct vertex_float16color quad[] = {
7295         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7296         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7297         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7298         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7299
7300         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7301         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7302         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7303         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7304
7305         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7306         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7307         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7308         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7309
7310         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7311         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7312         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7313         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7314     };
7315
7316     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7317     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7318
7319     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7320     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7321     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7322     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7323     IDirect3DDevice9_SetVertexShader(device, shader);
7324     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader 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_SetVertexDeclaration(device, vdecl);
7330         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7331         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7332         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7333         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7334         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7335         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7336         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7337         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7338         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7339
7340         hr = IDirect3DDevice9_EndScene(device);
7341         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7342     }
7343     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7344     color = getPixelColor(device, 480, 360);
7345     ok(color == 0x00ff0000,
7346        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7347     color = getPixelColor(device, 160, 120);
7348     ok(color == 0x00000000,
7349        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7350     color = getPixelColor(device, 160, 360);
7351     ok(color == 0x0000ff00,
7352        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7353     color = getPixelColor(device, 480, 120);
7354     ok(color == 0x000000ff,
7355        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7356
7357     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7358     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7359
7360     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7361                                              D3DPOOL_MANAGED, &buffer, NULL);
7362     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7363     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7364     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7365     memcpy(data, quad, sizeof(quad));
7366     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7367     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7368     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7369     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7370
7371     hr = IDirect3DDevice9_BeginScene(device);
7372     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7373     if(SUCCEEDED(hr)) {
7374             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7375             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7376             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7377             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7378             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7379             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7380             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7381             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7382
7383             hr = IDirect3DDevice9_EndScene(device);
7384             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7385     }
7386
7387     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7388     color = getPixelColor(device, 480, 360);
7389     ok(color == 0x00ff0000,
7390        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7391     color = getPixelColor(device, 160, 120);
7392     ok(color == 0x00000000,
7393        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7394     color = getPixelColor(device, 160, 360);
7395     ok(color == 0x0000ff00,
7396        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7397     color = getPixelColor(device, 480, 120);
7398     ok(color == 0x000000ff,
7399        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7400
7401     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7402     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7403     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7404     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7405     IDirect3DDevice9_SetVertexShader(device, NULL);
7406     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7407
7408     IDirect3DVertexDeclaration9_Release(vdecl);
7409     IDirect3DVertexShader9_Release(shader);
7410     IDirect3DVertexBuffer9_Release(buffer);
7411 }
7412
7413 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7414 {
7415     D3DCAPS9 caps;
7416     IDirect3DTexture9 *texture;
7417     HRESULT hr;
7418     D3DLOCKED_RECT rect;
7419     unsigned int x, y;
7420     DWORD *dst, color;
7421     const float quad[] = {
7422         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7423          1.0,   -1.0,   0.1,    1.2,   -0.2,
7424         -1.0,    1.0,   0.1,   -0.2,    1.2,
7425          1.0,    1.0,   0.1,    1.2,    1.2
7426     };
7427     memset(&caps, 0, sizeof(caps));
7428
7429     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7430     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7431     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7432         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7433         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7434            "Card has conditional NP2 support without power of two restriction set\n");
7435         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7436         return;
7437     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7438         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7439         return;
7440     }
7441
7442     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7443     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7444
7445     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7446     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7447
7448     memset(&rect, 0, sizeof(rect));
7449     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7450     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7451     for(y = 0; y < 10; y++) {
7452         for(x = 0; x < 10; x++) {
7453             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7454             if(x == 0 || x == 9 || y == 0 || y == 9) {
7455                 *dst = 0x00ff0000;
7456             } else {
7457                 *dst = 0x000000ff;
7458             }
7459         }
7460     }
7461     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7462     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7463
7464     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7465     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7466     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7467     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7468     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7469     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7470     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7471     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7472
7473     hr = IDirect3DDevice9_BeginScene(device);
7474     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7475     if(SUCCEEDED(hr)) {
7476         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7477         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7478
7479         hr = IDirect3DDevice9_EndScene(device);
7480         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7481     }
7482
7483     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7484
7485     color = getPixelColor(device,    1,  1);
7486     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7487     color = getPixelColor(device, 639, 479);
7488     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7489
7490     color = getPixelColor(device, 135, 101);
7491     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7492     color = getPixelColor(device, 140, 101);
7493     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7494     color = getPixelColor(device, 135, 105);
7495     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7496     color = getPixelColor(device, 140, 105);
7497     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7498
7499     color = getPixelColor(device, 135, 376);
7500     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7501     color = getPixelColor(device, 140, 376);
7502     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7503     color = getPixelColor(device, 135, 379);
7504     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7505     color = getPixelColor(device, 140, 379);
7506     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7507
7508     color = getPixelColor(device, 500, 101);
7509     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7510     color = getPixelColor(device, 504, 101);
7511     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7512     color = getPixelColor(device, 500, 105);
7513     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7514     color = getPixelColor(device, 504, 105);
7515     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7516
7517     color = getPixelColor(device, 500, 376);
7518     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7519     color = getPixelColor(device, 504, 376);
7520     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7521     color = getPixelColor(device, 500, 380);
7522     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7523     color = getPixelColor(device, 504, 380);
7524     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7525
7526     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7527     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7528     IDirect3DTexture9_Release(texture);
7529 }
7530
7531 static void vFace_register_test(IDirect3DDevice9 *device)
7532 {
7533     HRESULT hr;
7534     DWORD color;
7535     const DWORD shader_code[] = {
7536         0xffff0300,                                                             /* ps_3_0                     */
7537         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7538         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7539         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7540         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7541         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7542         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7543         0x0000ffff                                                              /* END                        */
7544     };
7545     IDirect3DPixelShader9 *shader;
7546     IDirect3DTexture9 *texture;
7547     IDirect3DSurface9 *surface, *backbuffer;
7548     const float quad[] = {
7549         -1.0,   -1.0,   0.1,
7550          1.0,   -1.0,   0.1,
7551         -1.0,    0.0,   0.1,
7552
7553          1.0,   -1.0,   0.1,
7554          1.0,    0.0,   0.1,
7555         -1.0,    0.0,   0.1,
7556
7557         -1.0,    0.0,   0.1,
7558         -1.0,    1.0,   0.1,
7559          1.0,    0.0,   0.1,
7560
7561          1.0,    0.0,   0.1,
7562         -1.0,    1.0,   0.1,
7563          1.0,    1.0,   0.1,
7564     };
7565     const float blit[] = {
7566          0.0,   -1.0,   0.1,    0.0,    0.0,
7567          1.0,   -1.0,   0.1,    1.0,    0.0,
7568          0.0,    1.0,   0.1,    0.0,    1.0,
7569          1.0,    1.0,   0.1,    1.0,    1.0,
7570     };
7571
7572     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7573     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7574     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7575     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7576     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7577     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7578     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7579     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7580     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7581     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7582     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7583     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7584
7585     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7586     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7587
7588     hr = IDirect3DDevice9_BeginScene(device);
7589     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7590     if(SUCCEEDED(hr)) {
7591         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7592         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7593         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7594         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7595         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7596         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7597         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7598         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7599         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7600         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7601         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7602
7603         /* Blit the texture onto the back buffer to make it visible */
7604         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7605         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7606         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7607         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7608         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7609         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7610         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7611         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7612         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7613         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7614
7615         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7616         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7617
7618         hr = IDirect3DDevice9_EndScene(device);
7619         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7620     }
7621
7622     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7623     color = getPixelColor(device, 160, 360);
7624     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7625     color = getPixelColor(device, 160, 120);
7626     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7627     color = getPixelColor(device, 480, 360);
7628     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7629     color = getPixelColor(device, 480, 120);
7630     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7631
7632     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7633     IDirect3DDevice9_SetTexture(device, 0, NULL);
7634     IDirect3DPixelShader9_Release(shader);
7635     IDirect3DSurface9_Release(surface);
7636     IDirect3DSurface9_Release(backbuffer);
7637     IDirect3DTexture9_Release(texture);
7638 }
7639
7640 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7641 {
7642     HRESULT hr;
7643     DWORD color;
7644     int i;
7645     D3DCAPS9 caps;
7646
7647     static const float quad[][7] = {
7648         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7649         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7650         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7651         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7652     };
7653
7654     static const D3DVERTEXELEMENT9 decl_elements[] = {
7655         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7656         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7657         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7658         D3DDECL_END()
7659     };
7660
7661     /* use asymmetric matrix to test loading */
7662     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7663
7664     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7665     IDirect3DTexture9           *texture            = NULL;
7666
7667     memset(&caps, 0, sizeof(caps));
7668     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7669     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7670     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7671         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7672         return;
7673     } else {
7674         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7675          * They report that it is not supported, but after that bump mapping works properly. So just test
7676          * if the format is generally supported, and check the BUMPENVMAP flag
7677          */
7678         IDirect3D9 *d3d9;
7679
7680         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7681         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7682                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7683         IDirect3D9_Release(d3d9);
7684         if(FAILED(hr)) {
7685             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7686             return;
7687         }
7688     }
7689
7690     /* Generate the textures */
7691     generate_bumpmap_textures(device);
7692
7693     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7694     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7695     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7696     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7697     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7698     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7699     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7700     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7701
7702     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7703     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7704     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7705     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7706     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7707     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7708
7709     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7710     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7711     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7712     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7713     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7714     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7715
7716     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7717     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7718
7719     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7720     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7721
7722     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7723     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7724
7725
7726     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7727     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7728     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7729     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7730
7731     hr = IDirect3DDevice9_BeginScene(device);
7732     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7733
7734     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7735     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7736
7737     hr = IDirect3DDevice9_EndScene(device);
7738     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7739
7740     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7741     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7742
7743     color = getPixelColor(device, 320-32, 240);
7744     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7745     color = getPixelColor(device, 320+32, 240);
7746     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7747     color = getPixelColor(device, 320, 240-32);
7748     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7749     color = getPixelColor(device, 320, 240+32);
7750     ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7751     color = getPixelColor(device, 320, 240);
7752     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7753     color = getPixelColor(device, 320+32, 240+32);
7754     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7755     color = getPixelColor(device, 320-32, 240+32);
7756     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7757     color = getPixelColor(device, 320+32, 240-32);
7758     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7759     color = getPixelColor(device, 320-32, 240-32);
7760     ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7761
7762     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7763     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7764     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7765
7766     for(i = 0; i < 2; i++) {
7767         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7768         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7769         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7770         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7771         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7772         IDirect3DTexture9_Release(texture); /* To destroy it */
7773     }
7774
7775     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7776     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7777     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7778     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7779
7780 }
7781
7782 static void stencil_cull_test(IDirect3DDevice9 *device) {
7783     HRESULT hr;
7784     IDirect3DSurface9 *depthstencil = NULL;
7785     D3DSURFACE_DESC desc;
7786     float quad1[] = {
7787         -1.0,   -1.0,   0.1,
7788          0.0,   -1.0,   0.1,
7789         -1.0,    0.0,   0.1,
7790          0.0,    0.0,   0.1,
7791     };
7792     float quad2[] = {
7793          0.0,   -1.0,   0.1,
7794          1.0,   -1.0,   0.1,
7795          0.0,    0.0,   0.1,
7796          1.0,    0.0,   0.1,
7797     };
7798     float quad3[] = {
7799         0.0,    0.0,   0.1,
7800         1.0,    0.0,   0.1,
7801         0.0,    1.0,   0.1,
7802         1.0,    1.0,   0.1,
7803     };
7804     float quad4[] = {
7805         -1.0,    0.0,   0.1,
7806          0.0,    0.0,   0.1,
7807         -1.0,    1.0,   0.1,
7808          0.0,    1.0,   0.1,
7809     };
7810     struct vertex painter[] = {
7811        {-1.0,   -1.0,   0.0,    0x00000000},
7812        { 1.0,   -1.0,   0.0,    0x00000000},
7813        {-1.0,    1.0,   0.0,    0x00000000},
7814        { 1.0,    1.0,   0.0,    0x00000000},
7815     };
7816     WORD indices_cw[]  = {0, 1, 3};
7817     WORD indices_ccw[] = {0, 2, 3};
7818     unsigned int i;
7819     DWORD color;
7820
7821     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7822     if(depthstencil == NULL) {
7823         skip("No depth stencil buffer\n");
7824         return;
7825     }
7826     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7827     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7828     IDirect3DSurface9_Release(depthstencil);
7829     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7830         skip("No 4 or 8 bit stencil surface\n");
7831         return;
7832     }
7833
7834     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7835     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7836     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7837
7838     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7839     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7840     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7841     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7842     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7843     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7844     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7845     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7846
7847     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7848     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7849     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7850     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7851     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7852     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7853
7854     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7855     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7856     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7857     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7858
7859     /* First pass: Fill the stencil buffer with some values... */
7860     hr = IDirect3DDevice9_BeginScene(device);
7861     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7862     if(SUCCEEDED(hr))
7863     {
7864         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7865         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7866         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7867                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7868         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7869                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7870
7871         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7872         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7873         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7874         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7875         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7876                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7877         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7878                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7879
7880         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7881         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7882         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7883                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7884         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7885                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7886
7887         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7888         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7889         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7890                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7891         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7892                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7893
7894         hr = IDirect3DDevice9_EndScene(device);
7895         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7896     }
7897
7898     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7899     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7900     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7901     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7902     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7903     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7904     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7905     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7906     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7908     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7909     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7910     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7911
7912     /* 2nd pass: Make the stencil values visible */
7913     hr = IDirect3DDevice9_BeginScene(device);
7914     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7915     if(SUCCEEDED(hr))
7916     {
7917         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7918         for(i = 0; i < 16; i++) {
7919             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7920             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7921
7922             painter[0].diffuse = (i * 16); /* Creates shades of blue */
7923             painter[1].diffuse = (i * 16);
7924             painter[2].diffuse = (i * 16);
7925             painter[3].diffuse = (i * 16);
7926             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7927             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7928         }
7929         hr = IDirect3DDevice9_EndScene(device);
7930         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7931     }
7932
7933     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7934     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7935
7936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7937     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7938
7939     color = getPixelColor(device, 160, 420);
7940     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7941     color = getPixelColor(device, 160, 300);
7942     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7943
7944     color = getPixelColor(device, 480, 420);
7945     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7946     color = getPixelColor(device, 480, 300);
7947     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
7948
7949     color = getPixelColor(device, 160, 180);
7950     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
7951     color = getPixelColor(device, 160, 60);
7952     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
7953
7954     color = getPixelColor(device, 480, 180);
7955     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
7956     color = getPixelColor(device, 480, 60);
7957     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7958 }
7959
7960 static void vpos_register_test(IDirect3DDevice9 *device)
7961 {
7962     HRESULT hr;
7963     DWORD color;
7964     const DWORD shader_code[] = {
7965     0xffff0300,                                                             /* ps_3_0                     */
7966     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
7967     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
7968     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
7969     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
7970     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
7971     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
7972     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
7973     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
7974     0x0000ffff                                                              /* end                        */
7975     };
7976     const DWORD shader_frac_code[] = {
7977     0xffff0300,                                                             /* ps_3_0                     */
7978     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
7979     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
7980     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
7981     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
7982     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7983     0x0000ffff                                                              /* end                        */
7984     };
7985     IDirect3DPixelShader9 *shader, *shader_frac;
7986     IDirect3DSurface9 *surface = NULL, *backbuffer;
7987     const float quad[] = {
7988         -1.0,   -1.0,   0.1,    0.0,    0.0,
7989          1.0,   -1.0,   0.1,    1.0,    0.0,
7990         -1.0,    1.0,   0.1,    0.0,    1.0,
7991          1.0,    1.0,   0.1,    1.0,    1.0,
7992     };
7993     D3DLOCKED_RECT lr;
7994     float constant[4] = {1.0, 0.0, 320, 240};
7995     DWORD *pos;
7996
7997     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7998     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7999     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8000     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8001     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8002     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8003     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8004     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8005     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8006     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8007     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8008     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8009
8010     hr = IDirect3DDevice9_BeginScene(device);
8011     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8012     if(SUCCEEDED(hr)) {
8013         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8014         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8015         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8016         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8017         hr = IDirect3DDevice9_EndScene(device);
8018         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8019     }
8020
8021     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8022     /* This has to be pixel exact */
8023     color = getPixelColor(device, 319, 239);
8024     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8025     color = getPixelColor(device, 320, 239);
8026     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8027     color = getPixelColor(device, 319, 240);
8028     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8029     color = getPixelColor(device, 320, 240);
8030     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8031
8032     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8033                                              &surface, NULL);
8034     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8035     hr = IDirect3DDevice9_BeginScene(device);
8036     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8037     if(SUCCEEDED(hr)) {
8038         constant[2] = 16; constant[3] = 16;
8039         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8040         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8041         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8042         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8043         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8044         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8045         hr = IDirect3DDevice9_EndScene(device);
8046         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8047     }
8048     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8049     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8050
8051     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8052     color = *pos & 0x00ffffff;
8053     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8054     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8055     color = *pos & 0x00ffffff;
8056     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8057     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8058     color = *pos & 0x00ffffff;
8059     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8060     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8061     color = *pos & 0x00ffffff;
8062     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8063
8064     hr = IDirect3DSurface9_UnlockRect(surface);
8065     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8066
8067     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8068      * have full control over the multisampling setting inside this test
8069      */
8070     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8071     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8072     hr = IDirect3DDevice9_BeginScene(device);
8073     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8074     if(SUCCEEDED(hr)) {
8075         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8076         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8077         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8078         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8079         hr = IDirect3DDevice9_EndScene(device);
8080         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8081     }
8082     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8083     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8084
8085     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8086     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8087
8088     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8089     color = *pos & 0x00ffffff;
8090     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8091
8092     hr = IDirect3DSurface9_UnlockRect(surface);
8093     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8094
8095     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8096     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8097     IDirect3DPixelShader9_Release(shader);
8098     IDirect3DPixelShader9_Release(shader_frac);
8099     if(surface) IDirect3DSurface9_Release(surface);
8100     IDirect3DSurface9_Release(backbuffer);
8101 }
8102
8103 static void pointsize_test(IDirect3DDevice9 *device)
8104 {
8105     HRESULT hr;
8106     D3DCAPS9 caps;
8107     D3DMATRIX matrix;
8108     D3DMATRIX identity;
8109     float ptsize, ptsize_orig;
8110     DWORD color;
8111
8112     const float vertices[] = {
8113         64,     64,     0.1,
8114         128,    64,     0.1,
8115         192,    64,     0.1,
8116         256,    64,     0.1,
8117         320,    64,     0.1,
8118         384,    64,     0.1
8119     };
8120
8121     /* 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 */
8122     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;
8123     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;
8124     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;
8125     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;
8126
8127     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;
8128     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;
8129     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;
8130     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;
8131
8132     memset(&caps, 0, sizeof(caps));
8133     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8134     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8135     if(caps.MaxPointSize < 32.0) {
8136         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8137         return;
8138     }
8139
8140     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8141     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8142     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8143     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8144     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8145     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8146     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8147     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8148
8149     hr = IDirect3DDevice9_BeginScene(device);
8150     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8151     if(SUCCEEDED(hr)) {
8152         ptsize = 16.0;
8153         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8154         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8157
8158         ptsize = 32.0;
8159         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8160         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8162         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8163
8164         ptsize = 31.5;
8165         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8166         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8167         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8168         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8169
8170         if(caps.MaxPointSize >= 64.0) {
8171             ptsize = 64.0;
8172             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8173             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8174             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8175             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8176
8177             ptsize = 63.75;
8178             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8179             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8180             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8181             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8182         }
8183
8184         ptsize = 1.0;
8185         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8186         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8187         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8188         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8189
8190         hr = IDirect3DDevice9_EndScene(device);
8191         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8192     }
8193     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8194     color = getPixelColor(device, 64-9, 64-9);
8195     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8196     color = getPixelColor(device, 64-8, 64-8);
8197     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8198     color = getPixelColor(device, 64-7, 64-7);
8199     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8200     color = getPixelColor(device, 64+7, 64+7);
8201     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8202     color = getPixelColor(device, 64+8, 64+8);
8203     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8204     color = getPixelColor(device, 64+9, 64+9);
8205     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8206
8207     color = getPixelColor(device, 128-17, 64-17);
8208     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8209     color = getPixelColor(device, 128-16, 64-16);
8210     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8211     color = getPixelColor(device, 128-15, 64-15);
8212     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8213     color = getPixelColor(device, 128+15, 64+15);
8214     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8215     color = getPixelColor(device, 128+16, 64+16);
8216     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8217     color = getPixelColor(device, 128+17, 64+17);
8218     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8219
8220     color = getPixelColor(device, 192-17, 64-17);
8221     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8222     color = getPixelColor(device, 192-16, 64-16);
8223     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8224     color = getPixelColor(device, 192-15, 64-15);
8225     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8226     color = getPixelColor(device, 192+15, 64+15);
8227     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8228     color = getPixelColor(device, 192+16, 64+16);
8229     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8230     color = getPixelColor(device, 192+17, 64+17);
8231     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8232
8233     if(caps.MaxPointSize >= 64.0) {
8234         color = getPixelColor(device, 256-33, 64-33);
8235         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8236         color = getPixelColor(device, 256-32, 64-32);
8237         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8238         color = getPixelColor(device, 256-31, 64-31);
8239         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8240         color = getPixelColor(device, 256+31, 64+31);
8241         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8242         color = getPixelColor(device, 256+32, 64+32);
8243         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8244         color = getPixelColor(device, 256+33, 64+33);
8245         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8246
8247         color = getPixelColor(device, 384-33, 64-33);
8248         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8249         color = getPixelColor(device, 384-32, 64-32);
8250         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8251         color = getPixelColor(device, 384-31, 64-31);
8252         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8253         color = getPixelColor(device, 384+31, 64+31);
8254         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8255         color = getPixelColor(device, 384+32, 64+32);
8256         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8257         color = getPixelColor(device, 384+33, 64+33);
8258         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8259     }
8260
8261     color = getPixelColor(device, 320-1, 64-1);
8262     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8263     color = getPixelColor(device, 320-0, 64-0);
8264     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8265     color = getPixelColor(device, 320+1, 64+1);
8266     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8267
8268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8270     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8272 }
8273
8274 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8275 {
8276     HRESULT hr;
8277     IDirect3DPixelShader9 *ps;
8278     IDirect3DTexture9 *tex1, *tex2;
8279     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8280     D3DCAPS9 caps;
8281     DWORD color;
8282     DWORD shader_code[] = {
8283     0xffff0300,                                                             /* ps_3_0             */
8284     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8285     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8286     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8287     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8288     0x0000ffff                                                              /* END                */
8289     };
8290     float quad[] = {
8291        -1.0,   -1.0,    0.1,
8292         1.0,   -1.0,    0.1,
8293        -1.0,    1.0,    0.1,
8294         1.0,    1.0,    0.1,
8295     };
8296     float texquad[] = {
8297        -1.0,   -1.0,    0.1,    0.0,    0.0,
8298         0.0,   -1.0,    0.1,    1.0,    0.0,
8299        -1.0,    1.0,    0.1,    0.0,    1.0,
8300         0.0,    1.0,    0.1,    1.0,    1.0,
8301
8302         0.0,   -1.0,    0.1,    0.0,    0.0,
8303         1.0,   -1.0,    0.1,    1.0,    0.0,
8304         0.0,    1.0,    0.1,    0.0,    1.0,
8305         1.0,    1.0,    0.1,    1.0,    1.0,
8306     };
8307
8308     memset(&caps, 0, sizeof(caps));
8309     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8310     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8311     if(caps.NumSimultaneousRTs < 2) {
8312         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8313         return;
8314     }
8315
8316     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8317     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8318
8319     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8320     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8321     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8322     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8323     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8324     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8325
8326     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8327     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8328     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8329     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8330     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8331     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8332
8333     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8334     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8335     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8336     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8337     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8338     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8339     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8340     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8341
8342     hr = IDirect3DDevice9_BeginScene(device);
8343     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8344     if(SUCCEEDED(hr)) {
8345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8346         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8347
8348         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8349         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8350         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8351         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8352         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8353         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8354         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8355         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8356
8357         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8358         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8360         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8361
8362         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8363         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8365         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8366
8367         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8368         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8369
8370         hr = IDirect3DDevice9_EndScene(device);
8371         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8372     }
8373
8374     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8375     color = getPixelColor(device, 160, 240);
8376     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8377     color = getPixelColor(device, 480, 240);
8378     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8379
8380     IDirect3DPixelShader9_Release(ps);
8381     IDirect3DTexture9_Release(tex1);
8382     IDirect3DTexture9_Release(tex2);
8383     IDirect3DSurface9_Release(surf1);
8384     IDirect3DSurface9_Release(surf2);
8385     IDirect3DSurface9_Release(backbuf);
8386 }
8387
8388 struct formats {
8389     const char *fmtName;
8390     D3DFORMAT textureFormat;
8391     DWORD resultColorBlending;
8392     DWORD resultColorNoBlending;
8393 };
8394
8395 const struct formats test_formats[] = {
8396   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8397   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8398   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8399   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8400   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8401   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8402   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8403   { NULL, 0 }
8404 };
8405
8406 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8407 {
8408     HRESULT hr;
8409     IDirect3DTexture9 *offscreenTexture = NULL;
8410     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8411     IDirect3D9 *d3d = NULL;
8412     DWORD color;
8413     int fmt_index;
8414
8415     static const float quad[][5] = {
8416         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8417         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8418         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8419         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8420     };
8421
8422     /* Quad with R=0x10, G=0x20 */
8423     static const struct vertex quad1[] = {
8424         {-1.0f, -1.0f, 0.1f, 0x80102000},
8425         {-1.0f,  1.0f, 0.1f, 0x80102000},
8426         { 1.0f, -1.0f, 0.1f, 0x80102000},
8427         { 1.0f,  1.0f, 0.1f, 0x80102000},
8428     };
8429
8430     /* Quad with R=0x20, G=0x10 */
8431     static const struct vertex quad2[] = {
8432         {-1.0f, -1.0f, 0.1f, 0x80201000},
8433         {-1.0f,  1.0f, 0.1f, 0x80201000},
8434         { 1.0f, -1.0f, 0.1f, 0x80201000},
8435         { 1.0f,  1.0f, 0.1f, 0x80201000},
8436     };
8437
8438     IDirect3DDevice9_GetDirect3D(device, &d3d);
8439
8440     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8441     ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8442     if(!backbuffer) {
8443         goto out;
8444     }
8445
8446     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8447     {
8448         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8449         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8450            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8451            continue;
8452         }
8453
8454         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8455         ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8456
8457         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8458         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8459         if(!offscreenTexture) {
8460             continue;
8461         }
8462
8463         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8464         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8465         if(!offscreen) {
8466             continue;
8467         }
8468
8469         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8470         ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8471
8472         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8473         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8474         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8475         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8476         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8477         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8478         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8479         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8480         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8481         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8482
8483         /* Below we will draw two quads with different colors and try to blend them together.
8484          * The result color is compared with the expected outcome.
8485          */
8486         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8487             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8488             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8489             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8490             ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8491
8492             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8493             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8494
8495             /* Draw a quad using color 0x0010200 */
8496             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8497             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8498             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8499             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8500             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8501             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8502
8503             /* Draw a quad using color 0x0020100 */
8504             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8505             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8506             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8507             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8508             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8509             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8510
8511             /* We don't want to blend the result on the backbuffer */
8512             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8513             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8514
8515             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8516             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8517             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8518             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8519             ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8520
8521             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8522             ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8523
8524             /* This time with the texture */
8525             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8526             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8527
8528             IDirect3DDevice9_EndScene(device);
8529         }
8530         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8531
8532
8533         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8534             /* Compare the color of the center quad with our expectation */
8535             color = getPixelColor(device, 320, 240);
8536             trace("[Blending] %s: expected=%x, result=%x\n", test_formats[fmt_index].fmtName, test_formats[fmt_index].resultColorBlending, color);
8537             ok(color == test_formats[fmt_index].resultColorBlending, "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8538         } else {
8539             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8540              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8541              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8542             color = getPixelColor(device, 320, 240);
8543             trace("[No blending] %s: expected %x  or 0x00ffffff, result=%x\n", test_formats[fmt_index].fmtName, test_formats[fmt_index].resultColorNoBlending, color);
8544             ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending), "Offscreen failed for %s: expected no color blending but received it anyway.\n", test_formats[fmt_index].fmtName);
8545         }
8546
8547         IDirect3DDevice9_SetTexture(device, 0, NULL);
8548         if(offscreenTexture) {
8549             IDirect3DTexture9_Release(offscreenTexture);
8550         }
8551         if(offscreen) {
8552             IDirect3DSurface9_Release(offscreen);
8553         }
8554     }
8555
8556 out:
8557     /* restore things */
8558     if(backbuffer) {
8559         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8560         IDirect3DSurface9_Release(backbuffer);
8561     }
8562 }
8563
8564 static void tssargtemp_test(IDirect3DDevice9 *device)
8565 {
8566     HRESULT hr;
8567     DWORD color;
8568     static const struct vertex quad[] = {
8569         {-1.0,     -1.0,    0.1,    0x00ff0000},
8570         { 1.0,     -1.0,    0.1,    0x00ff0000},
8571         {-1.0,      1.0,    0.1,    0x00ff0000},
8572         { 1.0,      1.0,    0.1,    0x00ff0000}
8573     };
8574     D3DCAPS9 caps;
8575
8576     memset(&caps, 0, sizeof(caps));
8577     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8578     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8579     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8580         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8581         return;
8582     }
8583
8584     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8585     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8586
8587     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8588     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8589     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8590     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8591
8592     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8593     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8594     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8595     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8596     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8597     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8598
8599     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8600     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8601     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8602     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8603     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8604     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8605
8606     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8607     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8608
8609     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8610     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8611     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8612     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8613
8614     hr = IDirect3DDevice9_BeginScene(device);
8615     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8616     if(SUCCEEDED(hr)) {
8617
8618         hr = IDirect3DDevice9_EndScene(device);
8619         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8620         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8621         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8622     }
8623     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8624     color = getPixelColor(device, 320, 240);
8625     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8626
8627     /* Set stage 1 back to default */
8628     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8629     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8630     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8631     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8632     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8633     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8634     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8635     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8636     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8637     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8638 }
8639
8640 START_TEST(visual)
8641 {
8642     IDirect3DDevice9 *device_ptr;
8643     D3DCAPS9 caps;
8644     HRESULT hr;
8645     DWORD color;
8646
8647     d3d9_handle = LoadLibraryA("d3d9.dll");
8648     if (!d3d9_handle)
8649     {
8650         skip("Could not load d3d9.dll\n");
8651         return;
8652     }
8653
8654     device_ptr = init_d3d9();
8655     if (!device_ptr)
8656     {
8657         skip("Creating the device failed\n");
8658         return;
8659     }
8660
8661     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
8662
8663     /* Check for the reliability of the returned data */
8664     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
8665     if(FAILED(hr))
8666     {
8667         trace("Clear failed, can't assure correctness of the test results, skipping\n");
8668         goto cleanup;
8669     }
8670     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
8671
8672     color = getPixelColor(device_ptr, 1, 1);
8673     if(color !=0x00ff0000)
8674     {
8675         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
8676         goto cleanup;
8677     }
8678
8679     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
8680     if(FAILED(hr))
8681     {
8682         trace("Clear failed, can't assure correctness of the test results, skipping\n");
8683         goto cleanup;
8684     }
8685     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
8686
8687     color = getPixelColor(device_ptr, 639, 479);
8688     if(color != 0x0000ddee)
8689     {
8690         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
8691         goto cleanup;
8692     }
8693
8694     /* Now execute the real tests */
8695     stretchrect_test(device_ptr);
8696     lighting_test(device_ptr);
8697     clear_test(device_ptr);
8698     fog_test(device_ptr);
8699     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
8700     {
8701         test_cube_wrap(device_ptr);
8702     } else {
8703         skip("No cube texture support\n");
8704     }
8705     z_range_test(device_ptr);
8706     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
8707     {
8708         maxmip_test(device_ptr);
8709     }
8710     else
8711     {
8712         skip("No mipmap support\n");
8713     }
8714     offscreen_test(device_ptr);
8715     alpha_test(device_ptr);
8716     shademode_test(device_ptr);
8717     srgbtexture_test(device_ptr);
8718     release_buffer_test(device_ptr);
8719     float_texture_test(device_ptr);
8720     g16r16_texture_test(device_ptr);
8721     pixelshader_blending_test(device_ptr);
8722     texture_transform_flags_test(device_ptr);
8723     autogen_mipmap_test(device_ptr);
8724     fixed_function_decl_test(device_ptr);
8725     conditional_np2_repeat_test(device_ptr);
8726     fixed_function_bumpmap_test(device_ptr);
8727     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
8728         stencil_cull_test(device_ptr);
8729     } else {
8730         skip("No two sided stencil support\n");
8731     }
8732     pointsize_test(device_ptr);
8733     tssargtemp_test(device_ptr);
8734
8735     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
8736     {
8737         test_constant_clamp_vs(device_ptr);
8738         test_compare_instructions(device_ptr);
8739     }
8740     else skip("No vs_1_1 support\n");
8741
8742     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
8743     {
8744         test_mova(device_ptr);
8745         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
8746             test_vshader_input(device_ptr);
8747             test_vshader_float16(device_ptr);
8748         } else {
8749             skip("No vs_3_0 support\n");
8750         }
8751     }
8752     else skip("No vs_2_0 support\n");
8753
8754     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
8755     {
8756         fog_with_shader_test(device_ptr);
8757         fog_srgbwrite_test(device_ptr);
8758     }
8759     else skip("No vs_1_1 and ps_1_1 support\n");
8760
8761     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
8762     {
8763         texbem_test(device_ptr);
8764         texdepth_test(device_ptr);
8765         texkill_test(device_ptr);
8766         x8l8v8u8_test(device_ptr);
8767         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
8768             constant_clamp_ps_test(device_ptr);
8769             cnd_test(device_ptr);
8770             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
8771                 dp2add_ps_test(device_ptr);
8772                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
8773                     nested_loop_test(device_ptr);
8774                     fixed_function_varying_test(device_ptr);
8775                     vFace_register_test(device_ptr);
8776                     vpos_register_test(device_ptr);
8777                     multiple_rendertargets_test(device_ptr);
8778                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
8779                         vshader_version_varying_test(device_ptr);
8780                         pshader_version_varying_test(device_ptr);
8781                     } else {
8782                         skip("No vs_3_0 support\n");
8783                     }
8784                 } else {
8785                     skip("No ps_3_0 support\n");
8786                 }
8787             } else {
8788                 skip("No ps_2_0 support\n");
8789             }
8790         }
8791     }
8792     else skip("No ps_1_1 support\n");
8793
8794 cleanup:
8795     if(device_ptr) {
8796         ULONG ref;
8797
8798         D3DPRESENT_PARAMETERS present_parameters;
8799         IDirect3DSwapChain9 *swapchain;
8800         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
8801         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
8802         IDirect3DSwapChain9_Release(swapchain);
8803         ref = IDirect3DDevice9_Release(device_ptr);
8804         DestroyWindow(present_parameters.hDeviceWindow);
8805         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
8806     }
8807 }