winmm: Fix a failing mixer test on 98 and ME.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 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 "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 static HWND create_window(void)
38 {
39     WNDCLASS wc = {0};
40     HWND ret;
41     wc.lpfnWndProc = DefWindowProc;
42     wc.lpszClassName = "d3d9_test_wc";
43     RegisterClass(&wc);
44
45     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46                         WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47     return ret;
48 }
49
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
51 {
52     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53     c1 >>= 8; c2 >>= 8;
54     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55     c1 >>= 8; c2 >>= 8;
56     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57     c1 >>= 8; c2 >>= 8;
58     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59     return TRUE;
60 }
61
62 /* Locks a given surface and returns the color at (x,y).  It's the caller's
63  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
65 {
66     DWORD color;
67     HRESULT hr;
68     D3DSURFACE_DESC desc;
69     RECT rectToLock = {x, y, x+1, y+1};
70     D3DLOCKED_RECT lockedRect;
71
72     hr = IDirect3DSurface9_GetDesc(surface, &desc);
73     if(FAILED(hr))  /* This is not a test */
74     {
75         trace("Can't get the surface description, hr=%08x\n", hr);
76         return 0xdeadbeef;
77     }
78
79     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80     if(FAILED(hr))  /* This is not a test */
81     {
82         trace("Can't lock the surface, hr=%08x\n", hr);
83         return 0xdeadbeef;
84     }
85     switch(desc.Format) {
86         case D3DFMT_A8R8G8B8:
87         {
88             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89             break;
90         }
91         default:
92             trace("Error: unknown surface format: %d\n", desc.Format);
93             color = 0xdeadbeef;
94             break;
95     }
96     hr = IDirect3DSurface9_UnlockRect(surface);
97     if(FAILED(hr))
98     {
99         trace("Can't unlock the surface, hr=%08x\n", hr);
100     }
101     return color;
102 }
103
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
105 {
106     DWORD ret;
107     IDirect3DSurface9 *surf;
108     HRESULT hr;
109     D3DLOCKED_RECT lockedRect;
110     RECT rectToLock = {x, y, x+1, y+1};
111
112     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113     if(FAILED(hr) || !surf )  /* This is not a test */
114     {
115         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116         return 0xdeadbeef;
117     }
118
119     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120     if(FAILED(hr))
121     {
122         trace("Can't read the front buffer data, hr=%08x\n", hr);
123         ret = 0xdeadbeed;
124         goto out;
125     }
126
127     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128     if(FAILED(hr))
129     {
130         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131         ret = 0xdeadbeec;
132         goto out;
133     }
134
135     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136      * really important for these tests
137      */
138     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139     hr = IDirect3DSurface9_UnlockRect(surf);
140     if(FAILED(hr))
141     {
142         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
143     }
144
145 out:
146     if(surf) IDirect3DSurface9_Release(surf);
147     return ret;
148 }
149
150 static IDirect3DDevice9 *init_d3d9(void)
151 {
152     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153     IDirect3D9 *d3d9_ptr = 0;
154     IDirect3DDevice9 *device_ptr = 0;
155     D3DPRESENT_PARAMETERS present_parameters;
156     HRESULT hr;
157     D3DADAPTER_IDENTIFIER9 identifier;
158
159     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161     if (!d3d9_create) return NULL;
162
163     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
165     if (!d3d9_ptr) return NULL;
166
167     ZeroMemory(&present_parameters, sizeof(present_parameters));
168     present_parameters.Windowed = FALSE;
169     present_parameters.hDeviceWindow = create_window();
170     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
171     present_parameters.BackBufferWidth = 640;
172     present_parameters.BackBufferHeight = 480;
173     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
174     present_parameters.EnableAutoDepthStencil = TRUE;
175     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
176
177     memset(&identifier, 0, sizeof(identifier));
178     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
179     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
180     trace("Driver string: \"%s\"\n", identifier.Driver);
181     trace("Description string: \"%s\"\n", identifier.Description);
182     trace("Device name string: \"%s\"\n", identifier.DeviceName);
183     trace("Driver version %d.%d.%d.%d\n",
184           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
185           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
186
187     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
188     if(FAILED(hr)) {
189         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
190         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191         if(FAILED(hr)) {
192             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
193         }
194     }
195     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
196
197     return device_ptr;
198 }
199
200 struct vertex
201 {
202     float x, y, z;
203     DWORD diffuse;
204 };
205
206 struct tvertex
207 {
208     float x, y, z, rhw;
209     DWORD diffuse;
210 };
211
212 struct nvertex
213 {
214     float x, y, z;
215     float nx, ny, nz;
216     DWORD diffuse;
217 };
218
219 static void lighting_test(IDirect3DDevice9 *device)
220 {
221     HRESULT hr;
222     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
223     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
224     DWORD color;
225
226     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
227                       0.0f, 1.0f, 0.0f, 0.0f,
228                       0.0f, 0.0f, 1.0f, 0.0f,
229                       0.0f, 0.0f, 0.0f, 1.0f };
230
231     struct vertex unlitquad[] =
232     {
233         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
234         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
235         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
236         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
237     };
238     struct vertex litquad[] =
239     {
240         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
241         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
242         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
243         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
244     };
245     struct nvertex unlitnquad[] =
246     {
247         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
248         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
249         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
250         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
251     };
252     struct nvertex litnquad[] =
253     {
254         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
255         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
256         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
257         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
258     };
259     WORD Indices[] = {0, 1, 2, 2, 3, 0};
260
261     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
262     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
263
264     /* Setup some states that may cause issues */
265     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
266     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
267     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
268     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
269     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
270     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
271     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
272     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
273     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
274     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
275     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
276     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
277     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
278     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
279     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
280     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
281     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
282     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
283     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
284     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
288     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
289
290     hr = IDirect3DDevice9_SetFVF(device, fvf);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
292
293     hr = IDirect3DDevice9_BeginScene(device);
294     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
295     if(hr == D3D_OK)
296     {
297         /* No lights are defined... That means, lit vertices should be entirely black */
298         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
299         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
301                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
302         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
303
304         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
305         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
306         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
307                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
308         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
309
310         hr = IDirect3DDevice9_SetFVF(device, nfvf);
311         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
312
313         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
314         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
315         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
316                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
317         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
318
319         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
320         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
321         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
322                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
323         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324
325         IDirect3DDevice9_EndScene(device);
326         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
327     }
328
329     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
330
331     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
332     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
333     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
334     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
335     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
336     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
337     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
338     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
339
340     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
341     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
342 }
343
344 static void clear_test(IDirect3DDevice9 *device)
345 {
346     /* Tests the correctness of clearing parameters */
347     HRESULT hr;
348     D3DRECT rect[2];
349     D3DRECT rect_negneg;
350     DWORD color;
351     D3DVIEWPORT9 old_vp, vp;
352     RECT scissor;
353     DWORD oldColorWrite;
354     BOOL invalid_clear_failed = FALSE;
355
356     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
357     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
358
359     /* Positive x, negative y */
360     rect[0].x1 = 0;
361     rect[0].y1 = 480;
362     rect[0].x2 = 320;
363     rect[0].y2 = 240;
364
365     /* Positive x, positive y */
366     rect[1].x1 = 0;
367     rect[1].y1 = 0;
368     rect[1].x2 = 320;
369     rect[1].y2 = 240;
370     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
371      * returns D3D_OK, but ignores the rectangle silently
372      */
373     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
374     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
375     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
376
377     /* negative x, negative y */
378     rect_negneg.x1 = 640;
379     rect_negneg.y1 = 240;
380     rect_negneg.x2 = 320;
381     rect_negneg.y2 = 0;
382     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
383     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
384     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
385
386     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
387
388     color = getPixelColor(device, 160, 360); /* lower left quad */
389     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
390     color = getPixelColor(device, 160, 120); /* upper left quad */
391     if(invalid_clear_failed) {
392         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
393         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
394     } else {
395         /* If the negative rectangle was dropped silently, the correct ones are cleared */
396         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
397     }
398     color = getPixelColor(device, 480, 360); /* lower right quad  */
399     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
400     color = getPixelColor(device, 480, 120); /* upper right quad */
401     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
402
403     /* Test how the viewport affects clears */
404     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
405     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
406     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
407     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
408
409     vp.X = 160;
410     vp.Y = 120;
411     vp.Width = 160;
412     vp.Height = 120;
413     vp.MinZ = 0.0;
414     vp.MaxZ = 1.0;
415     hr = IDirect3DDevice9_SetViewport(device, &vp);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
417     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
418     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
419
420     vp.X = 320;
421     vp.Y = 240;
422     vp.Width = 320;
423     vp.Height = 240;
424     vp.MinZ = 0.0;
425     vp.MaxZ = 1.0;
426     hr = IDirect3DDevice9_SetViewport(device, &vp);
427     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
428     rect[0].x1 = 160;
429     rect[0].y1 = 120;
430     rect[0].x2 = 480;
431     rect[0].y2 = 360;
432     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
434
435     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
436     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
437
438     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
439     color = getPixelColor(device, 158, 118);
440     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
441     color = getPixelColor(device, 162, 118);
442     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
443     color = getPixelColor(device, 158, 122);
444     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
445     color = getPixelColor(device, 162, 122);
446     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
447
448     color = getPixelColor(device, 318, 238);
449     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
450     color = getPixelColor(device, 322, 238);
451     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
452     color = getPixelColor(device, 318, 242);
453     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
454     color = getPixelColor(device, 322, 242);
455     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
456
457     color = getPixelColor(device, 478, 358);
458     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
459     color = getPixelColor(device, 482, 358);
460     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
461     color = getPixelColor(device, 478, 362);
462     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
463     color = getPixelColor(device, 482, 362);
464     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
465
466     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
467     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
468
469     scissor.left = 160;
470     scissor.right = 480;
471     scissor.top = 120;
472     scissor.bottom = 360;
473     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
474     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
475     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
476     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
477
478     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
479     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
480     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
481     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
482
483     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
484     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
485
486     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
487     color = getPixelColor(device, 158, 118);
488     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
489     color = getPixelColor(device, 162, 118);
490     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
491     color = getPixelColor(device, 158, 122);
492     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
493     color = getPixelColor(device, 162, 122);
494     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
495
496     color = getPixelColor(device, 158, 358);
497     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
498     color = getPixelColor(device, 162, 358);
499     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
500     color = getPixelColor(device, 158, 358);
501     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
502     color = getPixelColor(device, 162, 362);
503     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
504
505     color = getPixelColor(device, 478, 118);
506     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
507     color = getPixelColor(device, 478, 122);
508     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
509     color = getPixelColor(device, 482, 122);
510     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
511     color = getPixelColor(device, 482, 358);
512     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
513
514     color = getPixelColor(device, 478, 358);
515     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
516     color = getPixelColor(device, 478, 362);
517     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
518     color = getPixelColor(device, 482, 358);
519     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
520     color = getPixelColor(device, 482, 362);
521     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
522
523     color = getPixelColor(device, 318, 238);
524     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
525     color = getPixelColor(device, 318, 242);
526     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
527     color = getPixelColor(device, 322, 238);
528     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
529     color = getPixelColor(device, 322, 242);
530     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
531
532     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
533     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
534     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
535     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
536
537     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
538     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
539
540     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
541     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
542
543     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
544
545     /* Colorwriteenable does not affect the clear */
546     color = getPixelColor(device, 320, 240);
547     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
548 }
549
550 typedef struct {
551     float in[4];
552     DWORD out;
553 } test_data_t;
554
555 /*
556  *  c7      mova    ARGB            mov     ARGB
557  * -2.4     -2      0x00ffff00      -3      0x00ff0000
558  * -1.6     -2      0x00ffff00      -2      0x00ffff00
559  * -0.4      0      0x0000ffff      -1      0x0000ff00
560  *  0.4      0      0x0000ffff       0      0x0000ffff
561  *  1.6      2      0x00ff00ff       1      0x000000ff
562  *  2.4      2      0x00ff00ff       2      0x00ff00ff
563  */
564 static void test_mova(IDirect3DDevice9 *device)
565 {
566     static const DWORD mova_test[] = {
567         0xfffe0200,                                                             /* vs_2_0                       */
568         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
569         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
570         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
571         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
572         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
573         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
574         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
575         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
576         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
577         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
578         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
579         0x0000ffff                                                              /* END                          */
580     };
581     static const DWORD mov_test[] = {
582         0xfffe0101,                                                             /* vs_1_1                       */
583         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
584         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
585         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
586         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
587         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
588         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
589         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
590         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
591         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
592         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
593         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
594         0x0000ffff                                                              /* END                          */
595     };
596
597     static const test_data_t test_data[2][6] = {
598         {
599             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
600             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
601             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
602             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
603             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
604             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
605         },
606         {
607             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
608             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
609             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
610             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
611             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
612             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
613         }
614     };
615
616     static const float quad[][3] = {
617         {-1.0f, -1.0f, 0.0f},
618         {-1.0f,  1.0f, 0.0f},
619         { 1.0f, -1.0f, 0.0f},
620         { 1.0f,  1.0f, 0.0f},
621     };
622
623     static const D3DVERTEXELEMENT9 decl_elements[] = {
624         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
625         D3DDECL_END()
626     };
627
628     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
629     IDirect3DVertexShader9 *mova_shader = NULL;
630     IDirect3DVertexShader9 *mov_shader = NULL;
631     HRESULT hr;
632     UINT i, j;
633
634     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
635     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
636     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
637     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
638     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
639     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
640     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
641     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
642
643     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
644     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
645     for(j = 0; j < 2; ++j)
646     {
647         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
648         {
649             DWORD color;
650
651             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
652             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
653
654             hr = IDirect3DDevice9_BeginScene(device);
655             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
656
657             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
658             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
659
660             hr = IDirect3DDevice9_EndScene(device);
661             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
662
663             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
664             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
665
666             color = getPixelColor(device, 320, 240);
667             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
668                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
669
670             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
671             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
672         }
673         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
674         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
675     }
676
677     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
678     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
679
680     IDirect3DVertexDeclaration9_Release(vertex_declaration);
681     IDirect3DVertexShader9_Release(mova_shader);
682     IDirect3DVertexShader9_Release(mov_shader);
683 }
684
685 struct sVertex {
686     float x, y, z;
687     DWORD diffuse;
688     DWORD specular;
689 };
690
691 struct sVertexT {
692     float x, y, z, rhw;
693     DWORD diffuse;
694     DWORD specular;
695 };
696
697 static void fog_test(IDirect3DDevice9 *device)
698 {
699     HRESULT hr;
700     DWORD color;
701     BYTE r, g, b;
702     float start = 0.0f, end = 1.0f;
703     D3DCAPS9 caps;
704     int i;
705
706     /* Gets full z based fog with linear fog, no fog with specular color */
707     struct sVertex unstransformed_1[] = {
708         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
709         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
710         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
711         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
712     };
713     /* Ok, I am too lazy to deal with transform matrices */
714     struct sVertex unstransformed_2[] = {
715         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
716         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
717         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
718         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
719     };
720     /* Untransformed ones. Give them a different diffuse color to make the test look
721      * nicer. It also makes making sure that they are drawn correctly easier.
722      */
723     struct sVertexT transformed_1[] = {
724         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
725         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
726         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
727         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
728     };
729     struct sVertexT transformed_2[] = {
730         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
731         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
732         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
733         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
734     };
735     struct vertex rev_fog_quads[] = {
736        {-1.0,   -1.0,   0.1,    0x000000ff},
737        {-1.0,    0.0,   0.1,    0x000000ff},
738        { 0.0,    0.0,   0.1,    0x000000ff},
739        { 0.0,   -1.0,   0.1,    0x000000ff},
740
741        { 0.0,   -1.0,   0.9,    0x000000ff},
742        { 0.0,    0.0,   0.9,    0x000000ff},
743        { 1.0,    0.0,   0.9,    0x000000ff},
744        { 1.0,   -1.0,   0.9,    0x000000ff},
745
746        { 0.0,    0.0,   0.4,    0x000000ff},
747        { 0.0,    1.0,   0.4,    0x000000ff},
748        { 1.0,    1.0,   0.4,    0x000000ff},
749        { 1.0,    0.0,   0.4,    0x000000ff},
750
751        {-1.0,    0.0,   0.7,    0x000000ff},
752        {-1.0,    1.0,   0.7,    0x000000ff},
753        { 0.0,    1.0,   0.7,    0x000000ff},
754        { 0.0,    0.0,   0.7,    0x000000ff},
755     };
756     WORD Indices[] = {0, 1, 2, 2, 3, 0};
757
758     memset(&caps, 0, sizeof(caps));
759     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
760     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
761     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
762     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
763
764     /* Setup initial states: No lighting, fog on, fog color */
765     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
766     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
767     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
768     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
769     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
770     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
771
772     /* First test: Both table fog and vertex fog off */
773     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
774     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
775     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
776     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
777
778     /* Start = 0, end = 1. Should be default, but set them */
779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
780     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
781     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
782     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
783
784     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
785     {
786         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
787         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
788         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
789         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
790                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
791                                                      sizeof(unstransformed_1[0]));
792         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
793
794         /* That makes it use the Z value */
795         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
796         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
797         /* Untransformed, vertex fog != none (or table fog != none):
798          * Use the Z value as input into the equation
799          */
800         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
801                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
802                                                      sizeof(unstransformed_1[0]));
803         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
804
805         /* transformed verts */
806         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
807         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
808         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
809         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
810                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
811                                                      sizeof(transformed_1[0]));
812         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
813
814         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
815         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
816         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
817          * equation
818          */
819         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
820                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
821                                                      sizeof(transformed_2[0]));
822
823         hr = IDirect3DDevice9_EndScene(device);
824         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
825     }
826     else
827     {
828         ok(FALSE, "BeginScene failed\n");
829     }
830
831     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
832     color = getPixelColor(device, 160, 360);
833     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
834     color = getPixelColor(device, 160, 120);
835     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
836     color = getPixelColor(device, 480, 120);
837     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
838     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
839     {
840         color = getPixelColor(device, 480, 360);
841         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
842     }
843     else
844     {
845         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
846          * The settings above result in no fogging with vertex fog
847          */
848         color = getPixelColor(device, 480, 120);
849         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
850         trace("Info: Table fog not supported by this device\n");
851     }
852
853     /* Now test the special case fogstart == fogend */
854     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
855     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
856
857     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
858     {
859         start = 512;
860         end = 512;
861         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
862         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
863         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
864         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
865
866         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
867         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
868         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
869         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
870         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
871         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
872
873         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
874          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
875          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
876          * The third transformed quad remains unfogged because the fogcoords are read from the specular
877          * color and has fixed fogstart and fogend.
878          */
879         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
880                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
881                 sizeof(unstransformed_1[0]));
882         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
883         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
884                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
885                 sizeof(unstransformed_1[0]));
886         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
887
888         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
889         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
890         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
891         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
892                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
893                 sizeof(transformed_1[0]));
894         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
895
896         hr = IDirect3DDevice9_EndScene(device);
897         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
898     }
899     else
900     {
901         ok(FALSE, "BeginScene failed\n");
902     }
903     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
904     color = getPixelColor(device, 160, 360);
905     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
906     color = getPixelColor(device, 160, 120);
907     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
908     color = getPixelColor(device, 480, 120);
909     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
910
911     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
912      * but without shaders it seems to work everywhere
913      */
914     end = 0.2;
915     start = 0.8;
916     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
917     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
918     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
919     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
920     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
921     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
922
923     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
924      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
925      * so skip this for now
926      */
927     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
928         const char *mode = (i ? "table" : "vertex");
929         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
930         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
931         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
932         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
933         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
934         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
935         hr = IDirect3DDevice9_BeginScene(device);
936         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
937         if(SUCCEEDED(hr)) {
938             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
939                                 4,  5,  6,  6,  7, 4,
940                                 8,  9, 10, 10, 11, 8,
941                             12, 13, 14, 14, 15, 12};
942
943             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
944                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
945                     sizeof(rev_fog_quads[0]));
946
947             hr = IDirect3DDevice9_EndScene(device);
948             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
949         }
950         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
951         color = getPixelColor(device, 160, 360);
952         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
953
954         color = getPixelColor(device, 160, 120);
955         r = (color & 0x00ff0000) >> 16;
956         g = (color & 0x0000ff00) >>  8;
957         b = (color & 0x000000ff);
958         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
959            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
960
961         color = getPixelColor(device, 480, 120);
962         r = (color & 0x00ff0000) >> 16;
963         g = (color & 0x0000ff00) >>  8;
964         b = (color & 0x000000ff);
965         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
966            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
967
968         color = getPixelColor(device, 480, 360);
969         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
970
971         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
972             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
973             break;
974         }
975     }
976     /* Turn off the fog master switch to avoid confusing other tests */
977     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
978     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
979     start = 0.0;
980     end = 1.0;
981     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
982     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
983     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
984     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
985     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
986     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
987     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
988     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
989 }
990
991 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
992  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
993  * regardless of the actual addressing mode set. */
994 static void test_cube_wrap(IDirect3DDevice9 *device)
995 {
996     static const float quad[][6] = {
997         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
998         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
999         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1000         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1001     };
1002
1003     static const D3DVERTEXELEMENT9 decl_elements[] = {
1004         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1005         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1006         D3DDECL_END()
1007     };
1008
1009     static const struct {
1010         D3DTEXTUREADDRESS mode;
1011         const char *name;
1012     } address_modes[] = {
1013         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1014         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1015         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1016         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1017         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1018     };
1019
1020     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1021     IDirect3DCubeTexture9 *texture = NULL;
1022     IDirect3DSurface9 *surface = NULL;
1023     D3DLOCKED_RECT locked_rect;
1024     HRESULT hr;
1025     UINT x;
1026     INT y, face;
1027
1028     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1029     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1030     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1031     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1032
1033     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1034             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1035     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1036
1037     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1038     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1039
1040     for (y = 0; y < 128; ++y)
1041     {
1042         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1043         for (x = 0; x < 64; ++x)
1044         {
1045             *ptr++ = 0xffff0000;
1046         }
1047         for (x = 64; x < 128; ++x)
1048         {
1049             *ptr++ = 0xff0000ff;
1050         }
1051     }
1052
1053     hr = IDirect3DSurface9_UnlockRect(surface);
1054     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1055
1056     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1057             D3DPOOL_DEFAULT, &texture, NULL);
1058     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1059
1060     /* Create cube faces */
1061     for (face = 0; face < 6; ++face)
1062     {
1063         IDirect3DSurface9 *face_surface = NULL;
1064
1065         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1066         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1067
1068         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1069         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1070
1071         IDirect3DSurface9_Release(face_surface);
1072     }
1073
1074     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1075     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1076
1077     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1078     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1079     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1080     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1081     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1082     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1083
1084     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1085     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1086
1087     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1088     {
1089         DWORD color;
1090
1091         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1092         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1094         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1095
1096         hr = IDirect3DDevice9_BeginScene(device);
1097         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1098
1099         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1100         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1101
1102         hr = IDirect3DDevice9_EndScene(device);
1103         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1104
1105         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1106         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1107
1108         /* Due to the nature of this test, we sample essentially at the edge
1109          * between two faces. Because of this it's undefined from which face
1110          * the driver will sample. Fortunately that's not important for this
1111          * test, since all we care about is that it doesn't sample from the
1112          * other side of the surface or from the border. */
1113         color = getPixelColor(device, 320, 240);
1114         ok(color == 0x00ff0000 || color == 0x000000ff,
1115                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1116                 color, address_modes[x].name);
1117
1118         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1119         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1120     }
1121
1122     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1123     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1124
1125     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1126     IDirect3DCubeTexture9_Release(texture);
1127     IDirect3DSurface9_Release(surface);
1128 }
1129
1130 static void offscreen_test(IDirect3DDevice9 *device)
1131 {
1132     HRESULT hr;
1133     IDirect3DTexture9 *offscreenTexture = NULL;
1134     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1135     DWORD color;
1136
1137     static const float quad[][5] = {
1138         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1139         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1140         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1141         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1142     };
1143
1144     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1145     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1146
1147     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1148     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1149     if(!offscreenTexture) {
1150         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1151         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1152         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1153         if(!offscreenTexture) {
1154             skip("Cannot create an offscreen render target\n");
1155             goto out;
1156         }
1157     }
1158
1159     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1160     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1161     if(!backbuffer) {
1162         goto out;
1163     }
1164
1165     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1166     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1167     if(!offscreen) {
1168         goto out;
1169     }
1170
1171     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1172     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1173
1174     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1175     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1176     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1177     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1178     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1179     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1180     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1181     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1182     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1183     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1184
1185     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1186         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1187         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1188         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1189         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1190
1191         /* Draw without textures - Should result in a white quad */
1192         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1193         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1194
1195         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1196         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1197         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1198         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1199
1200         /* This time with the texture */
1201         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1202         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1203
1204         IDirect3DDevice9_EndScene(device);
1205     }
1206
1207     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1208
1209     /* Center quad - should be white */
1210     color = getPixelColor(device, 320, 240);
1211     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1212     /* Some quad in the cleared part of the texture */
1213     color = getPixelColor(device, 170, 240);
1214     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1215     /* Part of the originally cleared back buffer */
1216     color = getPixelColor(device, 10, 10);
1217     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1218     if(0) {
1219         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1220          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1221          * the offscreen rendering mode this test would succeed or fail
1222          */
1223         color = getPixelColor(device, 10, 470);
1224         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1225     }
1226
1227 out:
1228     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1229
1230     /* restore things */
1231     if(backbuffer) {
1232         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1233         IDirect3DSurface9_Release(backbuffer);
1234     }
1235     if(offscreenTexture) {
1236         IDirect3DTexture9_Release(offscreenTexture);
1237     }
1238     if(offscreen) {
1239         IDirect3DSurface9_Release(offscreen);
1240     }
1241 }
1242
1243 /* This test tests fog in combination with shaders.
1244  * What's tested: linear fog (vertex and table) with pixel shader
1245  *                linear table fog with non foggy vertex shader
1246  *                vertex fog with foggy vertex shader
1247  * What's not tested: non linear fog with shader
1248  *                    table fog with foggy vertex shader
1249  */
1250 static void fog_with_shader_test(IDirect3DDevice9 *device)
1251 {
1252     HRESULT hr;
1253     DWORD color;
1254     union {
1255         float f;
1256         DWORD i;
1257     } start, end;
1258     unsigned int i, j;
1259
1260     /* basic vertex shader without fog computation ("non foggy") */
1261     static const DWORD vertex_shader_code1[] = {
1262         0xfffe0101,                                                             /* vs_1_1                       */
1263         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1264         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1265         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1266         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1267         0x0000ffff
1268     };
1269     /* basic vertex shader with reversed fog computation ("foggy") */
1270     static const DWORD vertex_shader_code2[] = {
1271         0xfffe0101,                                                             /* vs_1_1                        */
1272         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1273         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1274         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1275         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1276         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1277         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1278         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1279         0x0000ffff
1280     };
1281     /* basic pixel shader */
1282     static const DWORD pixel_shader_code[] = {
1283         0xffff0101,                                                             /* ps_1_1     */
1284         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1285         0x0000ffff
1286     };
1287
1288     static struct vertex quad[] = {
1289         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1290         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1291         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1292         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1293     };
1294
1295     static const D3DVERTEXELEMENT9 decl_elements[] = {
1296         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1297         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1298         D3DDECL_END()
1299     };
1300
1301     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1302     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1303     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1304
1305     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1306     static const struct test_data_t {
1307         int vshader;
1308         int pshader;
1309         D3DFOGMODE vfog;
1310         D3DFOGMODE tfog;
1311         unsigned int color[11];
1312     } test_data[] = {
1313         /* only pixel shader: */
1314         {0, 1, 0, 3,
1315         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1316         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1317         {0, 1, 1, 3,
1318         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1319         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1320         {0, 1, 2, 3,
1321         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1322         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1323         {0, 1, 3, 0,
1324         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1325         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1326         {0, 1, 3, 3,
1327         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1328         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1329
1330         /* vertex shader */
1331         {1, 0, 0, 0,
1332         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1333          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1334         {1, 0, 0, 3,
1335         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1336         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1337         {1, 0, 1, 3,
1338         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1339         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1340
1341         {1, 0, 2, 3,
1342         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1343         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1344         {1, 0, 3, 3,
1345         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1346         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1347
1348         /* vertex shader and pixel shader */
1349         {1, 1, 0, 3,
1350         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1351         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1352         {1, 1, 1, 3,
1353         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1354         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1355         {1, 1, 2, 3,
1356         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1357         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1358
1359         {1, 1, 3, 3,
1360         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1361         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1362
1363
1364 #if 0  /* FIXME: these fail on GeForce 8500 */
1365         /* foggy vertex shader */
1366         {2, 0, 0, 0,
1367         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1368          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1369         {2, 0, 1, 0,
1370         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1371          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1372         {2, 0, 2, 0,
1373         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1374          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1375         {2, 0, 3, 0,
1376         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1377          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1378 #endif
1379
1380         /* foggy vertex shader and pixel shader */
1381         {2, 1, 0, 0,
1382         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1383          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1384         {2, 1, 1, 0,
1385         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1386          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1387         {2, 1, 2, 0,
1388         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1389          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1390         {2, 1, 3, 0,
1391         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1392          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1393
1394     };
1395
1396     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1397     start.f=0.1f;
1398     end.f=0.9f;
1399
1400     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1401     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1402     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1403     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1404     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1405     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1406     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1407     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1408
1409     /* Setup initial states: No lighting, fog on, fog color */
1410     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1411     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1412     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1413     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1415     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1416     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1417     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1418
1419     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1420     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1422     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1423
1424     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1426     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1427     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1428     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1429
1430     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1431     {
1432         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1433         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1434         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1435         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1436         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1437         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1438         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1439         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1440
1441         for(j=0; j < 11; j++)
1442         {
1443             /* Don't use the whole zrange to prevent rounding errors */
1444             quad[0].z = 0.001f + (float)j / 10.02f;
1445             quad[1].z = 0.001f + (float)j / 10.02f;
1446             quad[2].z = 0.001f + (float)j / 10.02f;
1447             quad[3].z = 0.001f + (float)j / 10.02f;
1448
1449             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1450             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1451
1452             hr = IDirect3DDevice9_BeginScene(device);
1453             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1454
1455             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1456             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1457
1458             hr = IDirect3DDevice9_EndScene(device);
1459             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1460
1461             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1462
1463             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1464             color = getPixelColor(device, 128, 240);
1465             ok(color_match(color, test_data[i].color[j], 13),
1466                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1467                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1468         }
1469     }
1470
1471     /* reset states */
1472     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1473     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1474     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1475     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1476     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1477     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1478     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1479     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1480
1481     IDirect3DVertexShader9_Release(vertex_shader[1]);
1482     IDirect3DVertexShader9_Release(vertex_shader[2]);
1483     IDirect3DPixelShader9_Release(pixel_shader[1]);
1484     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1485 }
1486
1487 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1488     unsigned int i, x, y;
1489     HRESULT hr;
1490     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1491     D3DLOCKED_RECT locked_rect;
1492
1493     /* Generate the textures */
1494     for(i=0; i<2; i++)
1495     {
1496         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1497                                             D3DPOOL_MANAGED, &texture[i], NULL);
1498         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1499
1500         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1501         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1502         for (y = 0; y < 128; ++y)
1503         {
1504             if(i)
1505             { /* Set up black texture with 2x2 texel white spot in the middle */
1506                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1507                 for (x = 0; x < 128; ++x)
1508                 {
1509                     if(y>62 && y<66 && x>62 && x<66)
1510                         *ptr++ = 0xffffffff;
1511                     else
1512                         *ptr++ = 0xff000000;
1513                 }
1514             }
1515             else
1516             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1517                * (if multiplied with bumpenvmat)
1518               */
1519                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1520                 for (x = 0; x < 128; ++x)
1521                 {
1522                     if(abs(x-64)>abs(y-64))
1523                     {
1524                         if(x < 64)
1525                             *ptr++ = 0xc000;
1526                         else
1527                             *ptr++ = 0x4000;
1528                     }
1529                     else
1530                     {
1531                         if(y < 64)
1532                             *ptr++ = 0x0040;
1533                         else
1534                             *ptr++ = 0x00c0;
1535                     }
1536                 }
1537             }
1538         }
1539         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1540         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1541
1542         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1543         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1544
1545         /* Disable texture filtering */
1546         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1547         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1548         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1549         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1550
1551         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1552         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1553         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1554         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1555     }
1556 }
1557
1558 /* test the behavior of the texbem instruction
1559  * with normal 2D and projective 2D textures
1560  */
1561 static void texbem_test(IDirect3DDevice9 *device)
1562 {
1563     HRESULT hr;
1564     DWORD color;
1565     int i;
1566
1567     static const DWORD pixel_shader_code[] = {
1568         0xffff0101,                         /* ps_1_1*/
1569         0x00000042, 0xb00f0000,             /* tex t0*/
1570         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1571         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1572         0x0000ffff
1573     };
1574     static const DWORD double_texbem_code[] =  {
1575         0xffff0103,                                         /* ps_1_3           */
1576         0x00000042, 0xb00f0000,                             /* tex t0           */
1577         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1578         0x00000042, 0xb00f0002,                             /* tex t2           */
1579         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1580         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1581         0x0000ffff                                          /* end              */
1582     };
1583
1584
1585     static const float quad[][7] = {
1586         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1587         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1588         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1589         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1590     };
1591     static const float quad_proj[][9] = {
1592         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1593         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1594         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1595         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1596     };
1597
1598     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1599         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1600         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1601         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1602         D3DDECL_END()
1603     },{
1604         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1605         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1606         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1607         D3DDECL_END()
1608     } };
1609
1610     /* use asymmetric matrix to test loading */
1611     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1612
1613     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1614     IDirect3DPixelShader9       *pixel_shader       = NULL;
1615     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1616     D3DLOCKED_RECT locked_rect;
1617
1618     generate_bumpmap_textures(device);
1619
1620     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1621     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1622     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1623     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1624     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1625
1626     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1627     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1628
1629     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1630     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1631
1632     for(i=0; i<2; i++)
1633     {
1634         if(i)
1635         {
1636             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1637             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1638         }
1639
1640         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1641         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1642         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1643         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1644
1645         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1646         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1647         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1648         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1649
1650         hr = IDirect3DDevice9_BeginScene(device);
1651         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1652
1653         if(!i)
1654             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1655         else
1656             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1657         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1658
1659         hr = IDirect3DDevice9_EndScene(device);
1660         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1661
1662         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1663         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1664
1665         color = getPixelColor(device, 320-32, 240);
1666         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1667         color = getPixelColor(device, 320+32, 240);
1668         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1669         color = getPixelColor(device, 320, 240-32);
1670         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1671         color = getPixelColor(device, 320, 240+32);
1672         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1673
1674         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1675         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1676         IDirect3DPixelShader9_Release(pixel_shader);
1677
1678         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1679         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1680         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1681     }
1682
1683     /* clean up */
1684     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1685     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1686
1687     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1688     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1689
1690     for(i=0; i<2; i++)
1691     {
1692         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1693         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1694         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1695         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1696         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1697         IDirect3DTexture9_Release(texture);
1698     }
1699
1700     /* Test double texbem */
1701     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1702     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1703     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1704     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1705     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1706     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1707     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1708     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1709
1710     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1711     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1712     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1713     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1714
1715     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1716     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1717
1718     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1719     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1720     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1721     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1722     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1723     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724
1725     {
1726         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1727 #define tex  0x00ff0000
1728 #define tex1 0x0000ff00
1729 #define origin 0x000000ff
1730         static const DWORD pixel_data[] = {
1731             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1732             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1733             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1734             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1735             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1736             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1737             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1738             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1739         };
1740 #undef tex1
1741 #undef tex2
1742 #undef origin
1743
1744         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1745         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1746         for(i = 0; i < 8; i++) {
1747             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1748         }
1749         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1750         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1751     }
1752
1753     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1754     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1755     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1756     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1757     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1758     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1759     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1760     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1761     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1762     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1764     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1765
1766     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1767     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1768     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1769     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1770     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1771     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1772
1773     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1774     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1775     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1776     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1777     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1778     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1779
1780     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1781     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1782     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1783     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1784     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1785     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1786     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1787     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1788
1789     hr = IDirect3DDevice9_BeginScene(device);
1790     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1791     if(SUCCEEDED(hr)) {
1792         static const float double_quad[] = {
1793             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1794              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1795             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1796              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1797         };
1798
1799         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1800         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1801         hr = IDirect3DDevice9_EndScene(device);
1802         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1803     }
1804     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1805     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1806     color = getPixelColor(device, 320, 240);
1807     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1808
1809     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1810     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1811     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1812     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1813     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1814     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1815     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1816     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1817     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1818     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1819
1820     IDirect3DPixelShader9_Release(pixel_shader);
1821     IDirect3DTexture9_Release(texture);
1822     IDirect3DTexture9_Release(texture1);
1823     IDirect3DTexture9_Release(texture2);
1824 }
1825
1826 static void z_range_test(IDirect3DDevice9 *device)
1827 {
1828     const struct vertex quad[] =
1829     {
1830         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1831         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1832         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1833         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1834     };
1835     const struct vertex quad2[] =
1836     {
1837         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1838         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1839         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1840         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1841     };
1842
1843     const struct tvertex quad3[] =
1844     {
1845         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1846         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1847         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1848         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1849     };
1850     const struct tvertex quad4[] =
1851     {
1852         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1853         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1854         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1855         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1856     };
1857     HRESULT hr;
1858     DWORD color;
1859     IDirect3DVertexShader9 *shader;
1860     IDirect3DVertexDeclaration9 *decl;
1861     D3DCAPS9 caps;
1862     const DWORD shader_code[] = {
1863         0xfffe0101,                                     /* vs_1_1           */
1864         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1865         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1866         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1867         0x0000ffff                                      /* end              */
1868     };
1869     static const D3DVERTEXELEMENT9 decl_elements[] = {
1870         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1871         D3DDECL_END()
1872     };
1873     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1874      * then call Present. Then clear the color buffer to make sure it has some defined content
1875      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1876      * by the depth value.
1877      */
1878     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1879     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1880     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1881     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1882
1883     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1884     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1885     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1886     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1887     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1888     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1889     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1890     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1891     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1892     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1893
1894     hr = IDirect3DDevice9_BeginScene(device);
1895     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1896     if(hr == D3D_OK)
1897     {
1898         /* Test the untransformed vertex path */
1899         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1900         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1901         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1902         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1903         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1904         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1905
1906         /* Test the transformed vertex path */
1907         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1908         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1909
1910         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1911         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1912         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1913         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1915         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1916
1917         hr = IDirect3DDevice9_EndScene(device);
1918         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1919     }
1920
1921     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1922     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1923
1924     /* Do not test the exact corner pixels, but go pretty close to them */
1925
1926     /* Clipped because z > 1.0 */
1927     color = getPixelColor(device, 28, 238);
1928     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1929     color = getPixelColor(device, 28, 241);
1930     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1931
1932     /* Not clipped, > z buffer clear value(0.75) */
1933     color = getPixelColor(device, 31, 238);
1934     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1935     color = getPixelColor(device, 31, 241);
1936     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1937     color = getPixelColor(device, 100, 238);
1938     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1939     color = getPixelColor(device, 100, 241);
1940     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1941
1942     /* Not clipped, < z buffer clear value */
1943     color = getPixelColor(device, 104, 238);
1944     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1945     color = getPixelColor(device, 104, 241);
1946     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1947     color = getPixelColor(device, 318, 238);
1948     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1949     color = getPixelColor(device, 318, 241);
1950     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1951
1952     /* Clipped because z < 0.0 */
1953     color = getPixelColor(device, 321, 238);
1954     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1955     color = getPixelColor(device, 321, 241);
1956     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1957
1958     /* Test the shader path */
1959     IDirect3DDevice9_GetDeviceCaps(device, &caps);
1960     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1961         skip("Vertex shaders not supported\n");
1962         goto out;
1963     }
1964     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1965     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
1966     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1967     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
1968
1969     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1970
1971     IDirect3DDevice9_SetVertexDeclaration(device, decl);
1972     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
1973     IDirect3DDevice9_SetVertexShader(device, shader);
1974     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
1975
1976     hr = IDirect3DDevice9_BeginScene(device);
1977     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1978     if(hr == D3D_OK)
1979     {
1980         float colorf[] = {1.0, 0.0, 0.0, 1.0};
1981         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1982         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1984         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1985         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1986         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1987         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1988         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1989         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1990
1991         hr = IDirect3DDevice9_EndScene(device);
1992         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1993     }
1994
1995     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1996     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
1997     IDirect3DDevice9_SetVertexShader(device, NULL);
1998     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
1999
2000     IDirect3DVertexDeclaration9_Release(decl);
2001     IDirect3DVertexShader9_Release(shader);
2002
2003     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2004     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2005     /* Z < 1.0 */
2006     color = getPixelColor(device, 28, 238);
2007     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2008
2009     /* 1.0 < z < 0.75 */
2010     color = getPixelColor(device, 31, 238);
2011     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2012     color = getPixelColor(device, 100, 238);
2013     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2014
2015     /* 0.75 < z < 0.0 */
2016     color = getPixelColor(device, 104, 238);
2017     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2018     color = getPixelColor(device, 318, 238);
2019     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2020
2021     /* 0.0 < z */
2022     color = getPixelColor(device, 321, 238);
2023     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2024
2025     out:
2026     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2027     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2028     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2029     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2030     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2031     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2032 }
2033
2034 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2035 {
2036     D3DSURFACE_DESC desc;
2037     D3DLOCKED_RECT l;
2038     HRESULT hr;
2039     unsigned int x, y;
2040     DWORD *mem;
2041
2042     memset(&desc, 0, sizeof(desc));
2043     memset(&l, 0, sizeof(l));
2044     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2045     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2046     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2047     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2048     if(FAILED(hr)) return;
2049
2050     for(y = 0; y < desc.Height; y++)
2051     {
2052         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2053         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2054         {
2055             mem[x] = color;
2056         }
2057     }
2058     hr = IDirect3DSurface9_UnlockRect(surface);
2059     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2060 }
2061
2062 /* This tests a variety of possible StretchRect() situations */
2063 static void stretchrect_test(IDirect3DDevice9 *device)
2064 {
2065     HRESULT hr;
2066     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2067     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2068     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2069     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2070     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2071     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2072     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2073     IDirect3DSurface9 *orig_rt = NULL;
2074     DWORD color;
2075
2076     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2077     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2078     if(!orig_rt) {
2079         goto out;
2080     }
2081
2082     /* Create our temporary surfaces in system memory */
2083     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2084     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2085     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2086     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2087
2088     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2089     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2090     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2091     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2092     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2093     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2094     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2095
2096     /* Create render target surfaces */
2097     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2098     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2099     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2100     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2101     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2102     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2103
2104     /* Create render target textures */
2105     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2106     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2107     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2108     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2109     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2110     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2111     if (tex_rt32) {
2112         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2113         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2114     }
2115     if (tex_rt64) {
2116         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2117         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2118     }
2119     if (tex_rt_dest64) {
2120         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2121         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2122     }
2123
2124     /* Create regular textures in D3DPOOL_DEFAULT */
2125     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2126     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2127     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2128     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2129     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2130     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2131     if (tex32) {
2132         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2133         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2134     }
2135     if (tex64) {
2136         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2137         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2138     }
2139     if (tex_dest64) {
2140         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2141         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2142     }
2143
2144     /*********************************************************************
2145      * Tests for when the source parameter is an offscreen plain surface *
2146      *********************************************************************/
2147
2148     /* Fill the offscreen 64x64 surface with green */
2149     if (surf_offscreen64)
2150         fill_surface(surf_offscreen64, 0xff00ff00);
2151
2152     /* offscreenplain ==> offscreenplain, same size */
2153     if(surf_offscreen64 && surf_offscreen_dest64) {
2154         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2155         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2156
2157         if (hr == D3D_OK) {
2158             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2159             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2160         }
2161     }
2162
2163     /* offscreenplain ==> rendertarget texture, same size */
2164     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2165         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2166         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2167
2168         /* We can't lock rendertarget textures, so copy to our temp surface first */
2169         if (hr == D3D_OK) {
2170             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2171             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2172         }
2173
2174         if (hr == D3D_OK) {
2175             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2176             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2177         }
2178     }
2179
2180     /* offscreenplain ==> rendertarget surface, same size */
2181     if(surf_offscreen64 && surf_rt_dest64) {
2182         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2183         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2184
2185         if (hr == D3D_OK) {
2186             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2187             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2188         }
2189     }
2190
2191     /* offscreenplain ==> texture, same size (should fail) */
2192     if(surf_offscreen64 && surf_tex_dest64) {
2193         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2194         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2195     }
2196
2197     /* Fill the smaller offscreen surface with red */
2198     fill_surface(surf_offscreen32, 0xffff0000);
2199
2200     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2201     if(surf_offscreen32 && surf_offscreen64) {
2202         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2203         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2204     }
2205
2206     /* offscreenplain ==> rendertarget texture, scaling */
2207     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2208         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2209         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2210
2211         /* We can't lock rendertarget textures, so copy to our temp surface first */
2212         if (hr == D3D_OK) {
2213             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2214             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2215         }
2216
2217         if (hr == D3D_OK) {
2218             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2219             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2220         }
2221     }
2222
2223     /* offscreenplain ==> rendertarget surface, scaling */
2224     if(surf_offscreen32 && surf_rt_dest64) {
2225         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2226         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2227
2228         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2229         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2230     }
2231
2232     /* offscreenplain ==> texture, scaling (should fail) */
2233     if(surf_offscreen32 && surf_tex_dest64) {
2234         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2235         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2236     }
2237
2238     /************************************************************
2239      * Tests for when the source parameter is a regular texture *
2240      ************************************************************/
2241
2242     /* Fill the surface of the regular texture with blue */
2243     if (surf_tex64 && surf_temp64) {
2244         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2245         fill_surface(surf_temp64, 0xff0000ff);
2246         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2247         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2248     }
2249
2250     /* texture ==> offscreenplain, same size */
2251     if(surf_tex64 && surf_offscreen64) {
2252         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2253         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2254     }
2255
2256     /* texture ==> rendertarget texture, same size */
2257     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2258         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2259         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2260
2261         /* We can't lock rendertarget textures, so copy to our temp surface first */
2262         if (hr == D3D_OK) {
2263             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2264             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2265         }
2266
2267         if (hr == D3D_OK) {
2268             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2269             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2270         }
2271     }
2272
2273     /* texture ==> rendertarget surface, same size */
2274     if(surf_tex64 && surf_rt_dest64) {
2275         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2276         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2277
2278         if (hr == D3D_OK) {
2279             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2280             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2281         }
2282     }
2283
2284     /* texture ==> texture, same size (should fail) */
2285     if(surf_tex64 && surf_tex_dest64) {
2286         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2287         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2288     }
2289
2290     /* Fill the surface of the smaller regular texture with red */
2291     if (surf_tex32 && surf_temp32) {
2292         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2293         fill_surface(surf_temp32, 0xffff0000);
2294         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2295         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2296     }
2297
2298     /* texture ==> offscreenplain, scaling (should fail) */
2299     if(surf_tex32 && surf_offscreen64) {
2300         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2301         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2302     }
2303
2304     /* texture ==> rendertarget texture, scaling */
2305     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2306         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2307         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2308
2309         /* We can't lock rendertarget textures, so copy to our temp surface first */
2310         if (hr == D3D_OK) {
2311             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2312             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2313         }
2314
2315         if (hr == D3D_OK) {
2316             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2317             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2318         }
2319     }
2320
2321     /* texture ==> rendertarget surface, scaling */
2322     if(surf_tex32 && surf_rt_dest64) {
2323         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2324         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2325
2326         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2327         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2328     }
2329
2330     /* texture ==> texture, scaling (should fail) */
2331     if(surf_tex32 && surf_tex_dest64) {
2332         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2333         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2334     }
2335
2336     /*****************************************************************
2337      * Tests for when the source parameter is a rendertarget texture *
2338      *****************************************************************/
2339
2340     /* Fill the surface of the rendertarget texture with white */
2341     if (surf_tex_rt64 && surf_temp64) {
2342         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2343         fill_surface(surf_temp64, 0xffffffff);
2344         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2345         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2346     }
2347
2348     /* rendertarget texture ==> offscreenplain, same size */
2349     if(surf_tex_rt64 && surf_offscreen64) {
2350         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2351         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2352     }
2353
2354     /* rendertarget texture ==> rendertarget texture, same size */
2355     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2356         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2357         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2358
2359         /* We can't lock rendertarget textures, so copy to our temp surface first */
2360         if (hr == D3D_OK) {
2361             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2362             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2363         }
2364
2365         if (hr == D3D_OK) {
2366             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2367             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2368         }
2369     }
2370
2371     /* rendertarget texture ==> rendertarget surface, same size */
2372     if(surf_tex_rt64 && surf_rt_dest64) {
2373         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2374         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2375
2376         if (hr == D3D_OK) {
2377             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2378             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2379         }
2380     }
2381
2382     /* rendertarget texture ==> texture, same size (should fail) */
2383     if(surf_tex_rt64 && surf_tex_dest64) {
2384         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2385         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2386     }
2387
2388     /* Fill the surface of the smaller rendertarget texture with red */
2389     if (surf_tex_rt32 && surf_temp32) {
2390         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2391         fill_surface(surf_temp32, 0xffff0000);
2392         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2393         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2394     }
2395
2396     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2397     if(surf_tex_rt32 && surf_offscreen64) {
2398         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2399         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2400     }
2401
2402     /* rendertarget texture ==> rendertarget texture, scaling */
2403     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2404         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2405         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2406
2407         /* We can't lock rendertarget textures, so copy to our temp surface first */
2408         if (hr == D3D_OK) {
2409             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2410             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2411         }
2412
2413         if (hr == D3D_OK) {
2414             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2415             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2416         }
2417     }
2418
2419     /* rendertarget texture ==> rendertarget surface, scaling */
2420     if(surf_tex_rt32 && surf_rt_dest64) {
2421         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2422         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2423
2424         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2425         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2426     }
2427
2428     /* rendertarget texture ==> texture, scaling (should fail) */
2429     if(surf_tex_rt32 && surf_tex_dest64) {
2430         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2431         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2432     }
2433
2434     /*****************************************************************
2435      * Tests for when the source parameter is a rendertarget surface *
2436      *****************************************************************/
2437
2438     /* Fill the surface of the rendertarget surface with black */
2439     if (surf_rt64)
2440         fill_surface(surf_rt64, 0xff000000);
2441
2442     /* rendertarget texture ==> offscreenplain, same size */
2443     if(surf_rt64 && surf_offscreen64) {
2444         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2445         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2446     }
2447
2448     /* rendertarget surface ==> rendertarget texture, same size */
2449     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2450         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2451         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2452
2453         /* We can't lock rendertarget textures, so copy to our temp surface first */
2454         if (hr == D3D_OK) {
2455             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2456             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2457         }
2458
2459         if (hr == D3D_OK) {
2460             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2461             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2462         }
2463     }
2464
2465     /* rendertarget surface ==> rendertarget surface, same size */
2466     if(surf_rt64 && surf_rt_dest64) {
2467         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2468         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2469
2470         if (hr == D3D_OK) {
2471             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2472             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2473         }
2474     }
2475
2476     /* rendertarget surface ==> texture, same size (should fail) */
2477     if(surf_rt64 && surf_tex_dest64) {
2478         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2479         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2480     }
2481
2482     /* Fill the surface of the smaller rendertarget texture with red */
2483     if (surf_rt32)
2484         fill_surface(surf_rt32, 0xffff0000);
2485
2486     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2487     if(surf_rt32 && surf_offscreen64) {
2488         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2489         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2490     }
2491
2492     /* rendertarget surface ==> rendertarget texture, scaling */
2493     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2495         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2496
2497         /* We can't lock rendertarget textures, so copy to our temp surface first */
2498         if (hr == D3D_OK) {
2499             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2500             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2501         }
2502
2503         if (hr == D3D_OK) {
2504             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2505             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2506         }
2507     }
2508
2509     /* rendertarget surface ==> rendertarget surface, scaling */
2510     if(surf_rt32 && surf_rt_dest64) {
2511         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2512         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2513
2514         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2515         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2516     }
2517
2518     /* rendertarget surface ==> texture, scaling (should fail) */
2519     if(surf_rt32 && surf_tex_dest64) {
2520         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2521         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2522     }
2523
2524     /* TODO: Test when source and destination RECT parameters are given... */
2525     /* TODO: Test format conversions */
2526
2527
2528 out:
2529     /* Clean up */
2530     if (surf_rt32)
2531         IDirect3DSurface9_Release(surf_rt32);
2532     if (surf_rt64)
2533         IDirect3DSurface9_Release(surf_rt64);
2534     if (surf_rt_dest64)
2535         IDirect3DSurface9_Release(surf_rt_dest64);
2536     if (surf_temp32)
2537         IDirect3DSurface9_Release(surf_temp32);
2538     if (surf_temp64)
2539         IDirect3DSurface9_Release(surf_temp64);
2540     if (surf_offscreen32)
2541         IDirect3DSurface9_Release(surf_offscreen32);
2542     if (surf_offscreen64)
2543         IDirect3DSurface9_Release(surf_offscreen64);
2544     if (surf_offscreen_dest64)
2545         IDirect3DSurface9_Release(surf_offscreen_dest64);
2546
2547     if (tex_rt32) {
2548         if (surf_tex_rt32)
2549             IDirect3DSurface9_Release(surf_tex_rt32);
2550         IDirect3DTexture9_Release(tex_rt32);
2551     }
2552     if (tex_rt64) {
2553         if (surf_tex_rt64)
2554             IDirect3DSurface9_Release(surf_tex_rt64);
2555         IDirect3DTexture9_Release(tex_rt64);
2556     }
2557     if (tex_rt_dest64) {
2558         if (surf_tex_rt_dest64)
2559             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2560         IDirect3DTexture9_Release(tex_rt_dest64);
2561     }
2562     if (tex32) {
2563         if (surf_tex32)
2564             IDirect3DSurface9_Release(surf_tex32);
2565         IDirect3DTexture9_Release(tex32);
2566     }
2567     if (tex64) {
2568         if (surf_tex64)
2569             IDirect3DSurface9_Release(surf_tex64);
2570         IDirect3DTexture9_Release(tex64);
2571     }
2572     if (tex_dest64) {
2573         if (surf_tex_dest64)
2574             IDirect3DSurface9_Release(surf_tex_dest64);
2575         IDirect3DTexture9_Release(tex_dest64);
2576     }
2577
2578     if (orig_rt) {
2579         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2580         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2581         IDirect3DSurface9_Release(orig_rt);
2582     }
2583 }
2584
2585 static void maxmip_test(IDirect3DDevice9 *device)
2586 {
2587     IDirect3DTexture9 *texture = NULL;
2588     IDirect3DSurface9 *surface = NULL;
2589     HRESULT hr;
2590     DWORD color;
2591     const float quads[] = {
2592         -1.0,   -1.0,   0.0,    0.0,    0.0,
2593         -1.0,    0.0,   0.0,    0.0,    1.0,
2594          0.0,   -1.0,   0.0,    1.0,    0.0,
2595          0.0,    0.0,   0.0,    1.0,    1.0,
2596
2597          0.0,   -1.0,   0.0,    0.0,    0.0,
2598          0.0,    0.0,   0.0,    0.0,    1.0,
2599          1.0,   -1.0,   0.0,    1.0,    0.0,
2600          1.0,    0.0,   0.0,    1.0,    1.0,
2601
2602          0.0,    0.0,   0.0,    0.0,    0.0,
2603          0.0,    1.0,   0.0,    0.0,    1.0,
2604          1.0,    0.0,   0.0,    1.0,    0.0,
2605          1.0,    1.0,   0.0,    1.0,    1.0,
2606
2607         -1.0,    0.0,   0.0,    0.0,    0.0,
2608         -1.0,    1.0,   0.0,    0.0,    1.0,
2609          0.0,    0.0,   0.0,    1.0,    0.0,
2610          0.0,    1.0,   0.0,    1.0,    1.0,
2611     };
2612
2613     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2614     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2615
2616     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2617                                         &texture, NULL);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2619     if(!texture)
2620     {
2621         skip("Failed to create test texture\n");
2622         return;
2623     }
2624
2625     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2626     fill_surface(surface, 0xffff0000);
2627     IDirect3DSurface9_Release(surface);
2628     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2629     fill_surface(surface, 0xff00ff00);
2630     IDirect3DSurface9_Release(surface);
2631     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2632     fill_surface(surface, 0xff0000ff);
2633     IDirect3DSurface9_Release(surface);
2634
2635     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2636     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2637     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2638     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2639
2640     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2641     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2642
2643     hr = IDirect3DDevice9_BeginScene(device);
2644     if(SUCCEEDED(hr))
2645     {
2646         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2647         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2648         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2649         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2650
2651         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2652         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2653         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2654         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2655
2656         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2657         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2658         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2659         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2660
2661         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2662         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2663         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2664         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2665         hr = IDirect3DDevice9_EndScene(device);
2666     }
2667
2668     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2669     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2670     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2671     color = getPixelColor(device, 160, 360);
2672     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2673     color = getPixelColor(device, 160, 120);
2674     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2675     color = getPixelColor(device, 480, 120);
2676     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2677     color = getPixelColor(device, 480, 360);
2678     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2679
2680     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2681     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2682
2683     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2684     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2685
2686     hr = IDirect3DDevice9_BeginScene(device);
2687     if(SUCCEEDED(hr))
2688     {
2689         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2690         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2691         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2692         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2693
2694         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2695         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2696         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2697         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2698
2699         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2700         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2701         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2702         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2703
2704         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2705         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2706         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2707         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2708         hr = IDirect3DDevice9_EndScene(device);
2709     }
2710
2711     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2712     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2713     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2714     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2715
2716     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2717     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2718     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2719      * samples from the highest level in the texture(level 2)
2720      */
2721     color = getPixelColor(device, 160, 360);
2722     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2723     color = getPixelColor(device, 160, 120);
2724     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2725     color = getPixelColor(device, 480, 120);
2726     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2727     color = getPixelColor(device, 480, 360);
2728     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2729
2730     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2731     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2732     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2733     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2734     IDirect3DTexture9_Release(texture);
2735 }
2736
2737 static void release_buffer_test(IDirect3DDevice9 *device)
2738 {
2739     IDirect3DVertexBuffer9 *vb = NULL;
2740     IDirect3DIndexBuffer9 *ib = NULL;
2741     HRESULT hr;
2742     BYTE *data;
2743     long ref;
2744
2745     static const struct vertex quad[] = {
2746         {-1.0,      -1.0,       0.1,        0xffff0000},
2747         {-1.0,       1.0,       0.1,        0xffff0000},
2748         { 1.0,       1.0,       0.1,        0xffff0000},
2749
2750         {-1.0,      -1.0,       0.1,        0xff00ff00},
2751         {-1.0,       1.0,       0.1,        0xff00ff00},
2752         { 1.0,       1.0,       0.1,        0xff00ff00}
2753     };
2754     short indices[] = {3, 4, 5};
2755
2756     /* Index and vertex buffers should always be creatable */
2757     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2758                                               D3DPOOL_MANAGED, &vb, NULL);
2759     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2760     if(!vb) {
2761         skip("Failed to create a vertex buffer\n");
2762         return;
2763     }
2764     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2765     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2766     if(!ib) {
2767         skip("Failed to create an index buffer\n");
2768         return;
2769     }
2770
2771     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2772     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2773     memcpy(data, quad, sizeof(quad));
2774     hr = IDirect3DVertexBuffer9_Unlock(vb);
2775     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2776
2777     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2778     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2779     memcpy(data, indices, sizeof(indices));
2780     hr = IDirect3DIndexBuffer9_Unlock(ib);
2781     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2782
2783     hr = IDirect3DDevice9_SetIndices(device, ib);
2784     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2785     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2786     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2787     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2788     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2789
2790     /* Now destroy the bound index buffer and draw again */
2791     ref = IDirect3DIndexBuffer9_Release(ib);
2792     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2793
2794     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2795     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2796
2797     hr = IDirect3DDevice9_BeginScene(device);
2798     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2799     if(SUCCEEDED(hr))
2800     {
2801         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2802          * making assumptions about the indices or vertices
2803          */
2804         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2805         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2806         hr = IDirect3DDevice9_EndScene(device);
2807         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2808     }
2809
2810     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2811     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2812
2813     hr = IDirect3DDevice9_SetIndices(device, NULL);
2814     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2815     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2816     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2817
2818     /* Index buffer was already destroyed as part of the test */
2819     IDirect3DVertexBuffer9_Release(vb);
2820 }
2821
2822 static void float_texture_test(IDirect3DDevice9 *device)
2823 {
2824     IDirect3D9 *d3d = NULL;
2825     HRESULT hr;
2826     IDirect3DTexture9 *texture = NULL;
2827     D3DLOCKED_RECT lr;
2828     float *data;
2829     DWORD color;
2830     float quad[] = {
2831         -1.0,      -1.0,       0.1,     0.0,    0.0,
2832         -1.0,       1.0,       0.1,     0.0,    1.0,
2833          1.0,      -1.0,       0.1,     1.0,    0.0,
2834          1.0,       1.0,       0.1,     1.0,    1.0,
2835     };
2836
2837     memset(&lr, 0, sizeof(lr));
2838     IDirect3DDevice9_GetDirect3D(device, &d3d);
2839     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2840                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2841         skip("D3DFMT_R32F textures not supported\n");
2842         goto out;
2843     }
2844
2845     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2846                                         D3DPOOL_MANAGED, &texture, NULL);
2847     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2848     if(!texture) {
2849         skip("Failed to create R32F texture\n");
2850         goto out;
2851     }
2852
2853     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2854     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2855     data = lr.pBits;
2856     *data = 0.0;
2857     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2858     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2859
2860     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2861     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2862
2863     hr = IDirect3DDevice9_BeginScene(device);
2864     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2865     if(SUCCEEDED(hr))
2866     {
2867         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2868         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2869
2870         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2871         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2872
2873         hr = IDirect3DDevice9_EndScene(device);
2874         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2875     }
2876     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2877     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2878
2879     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2880     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2881
2882     color = getPixelColor(device, 240, 320);
2883     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2884
2885 out:
2886     if(texture) IDirect3DTexture9_Release(texture);
2887     IDirect3D9_Release(d3d);
2888 }
2889
2890 static void g16r16_texture_test(IDirect3DDevice9 *device)
2891 {
2892     IDirect3D9 *d3d = NULL;
2893     HRESULT hr;
2894     IDirect3DTexture9 *texture = NULL;
2895     D3DLOCKED_RECT lr;
2896     DWORD *data;
2897     DWORD color, red, green, blue;
2898     float quad[] = {
2899        -1.0,      -1.0,       0.1,     0.0,    0.0,
2900        -1.0,       1.0,       0.1,     0.0,    1.0,
2901         1.0,      -1.0,       0.1,     1.0,    0.0,
2902         1.0,       1.0,       0.1,     1.0,    1.0,
2903     };
2904
2905     memset(&lr, 0, sizeof(lr));
2906     IDirect3DDevice9_GetDirect3D(device, &d3d);
2907     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2908        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2909            skip("D3DFMT_G16R16 textures not supported\n");
2910            goto out;
2911     }
2912
2913     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2914                                         D3DPOOL_MANAGED, &texture, NULL);
2915     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2916     if(!texture) {
2917         skip("Failed to create D3DFMT_G16R16 texture\n");
2918         goto out;
2919     }
2920
2921     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2922     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2923     data = lr.pBits;
2924     *data = 0x0f00f000;
2925     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2926     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2927
2928     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2929     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2930
2931     hr = IDirect3DDevice9_BeginScene(device);
2932     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2933     if(SUCCEEDED(hr))
2934     {
2935         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2936         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2937
2938         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2939         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2940
2941         hr = IDirect3DDevice9_EndScene(device);
2942         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2943     }
2944     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2945     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2946
2947     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2948     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2949
2950     color = getPixelColor(device, 240, 320);
2951     red   = (color & 0x00ff0000) >> 16;
2952     green = (color & 0x0000ff00) >>  8;
2953     blue  = (color & 0x000000ff) >>  0;
2954     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2955        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2956
2957 out:
2958     if(texture) IDirect3DTexture9_Release(texture);
2959     IDirect3D9_Release(d3d);
2960 }
2961
2962 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2963 {
2964     HRESULT hr;
2965     IDirect3D9 *d3d;
2966     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2967     D3DCAPS9 caps;
2968     IDirect3DTexture9 *texture = NULL;
2969     IDirect3DVolumeTexture9 *volume = NULL;
2970     unsigned int x, y, z;
2971     D3DLOCKED_RECT lr;
2972     D3DLOCKED_BOX lb;
2973     DWORD color;
2974     UINT w, h;
2975     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2976     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2977                            0.0, 1.0, 0.0, 0.0,
2978                            0.0, 0.0, 1.0, 0.0,
2979                            0.0, 0.0, 0.0, 1.0};
2980     static const D3DVERTEXELEMENT9 decl_elements[] = {
2981         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2982         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2983         D3DDECL_END()
2984     };
2985     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2986         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2987         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2988         D3DDECL_END()
2989     };
2990     static const D3DVERTEXELEMENT9 decl_elements3[] = {
2991         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2992         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2993         D3DDECL_END()
2994     };
2995     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2996                                                  0x00, 0xff, 0x00, 0x00,
2997                                                  0x00, 0x00, 0x00, 0x00,
2998                                                  0x00, 0x00, 0x00, 0x00};
2999
3000     memset(&lr, 0, sizeof(lr));
3001     memset(&lb, 0, sizeof(lb));
3002     IDirect3DDevice9_GetDirect3D(device, &d3d);
3003     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3004                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3005         fmt = D3DFMT_A16B16G16R16;
3006     }
3007     IDirect3D9_Release(d3d);
3008
3009     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3010     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3011     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3012     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3013     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3014     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3015     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3016     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3017     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3018     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3019     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3020     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3021     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3022     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3023     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3024     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3025     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3026     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3027     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3028     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3029     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3030     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3031     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3032     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3033
3034     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3035     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3036     w = min(1024, caps.MaxTextureWidth);
3037     h = min(1024, caps.MaxTextureHeight);
3038     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3039                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3040     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3041     if(!texture) {
3042         skip("Failed to create the test texture\n");
3043         return;
3044     }
3045
3046     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3047      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3048      * 1.0 in red and green for the x and y coords
3049      */
3050     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3051     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3052     for(y = 0; y < h; y++) {
3053         for(x = 0; x < w; x++) {
3054             double r_f = (double) y / (double) h;
3055             double g_f = (double) x / (double) w;
3056             if(fmt == D3DFMT_A16B16G16R16) {
3057                 unsigned short r, g;
3058                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3059                 r = (unsigned short) (r_f * 65536.0);
3060                 g = (unsigned short) (g_f * 65536.0);
3061                 dst[0] = r;
3062                 dst[1] = g;
3063                 dst[2] = 0;
3064                 dst[3] = 65535;
3065             } else {
3066                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3067                 unsigned char r = (unsigned char) (r_f * 255.0);
3068                 unsigned char g = (unsigned char) (g_f * 255.0);
3069                 dst[0] = 0;
3070                 dst[1] = g;
3071                 dst[2] = r;
3072                 dst[3] = 255;
3073             }
3074         }
3075     }
3076     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3077     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3078     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3079     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3080
3081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3082     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3083     hr = IDirect3DDevice9_BeginScene(device);
3084     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3085     if(SUCCEEDED(hr))
3086     {
3087         float quad1[] = {
3088             -1.0,      -1.0,       0.1,     1.0,    1.0,
3089             -1.0,       0.0,       0.1,     1.0,    1.0,
3090              0.0,      -1.0,       0.1,     1.0,    1.0,
3091              0.0,       0.0,       0.1,     1.0,    1.0,
3092         };
3093         float quad2[] = {
3094             -1.0,       0.0,       0.1,     1.0,    1.0,
3095             -1.0,       1.0,       0.1,     1.0,    1.0,
3096              0.0,       0.0,       0.1,     1.0,    1.0,
3097              0.0,       1.0,       0.1,     1.0,    1.0,
3098         };
3099         float quad3[] = {
3100              0.0,       0.0,       0.1,     0.5,    0.5,
3101              0.0,       1.0,       0.1,     0.5,    0.5,
3102              1.0,       0.0,       0.1,     0.5,    0.5,
3103              1.0,       1.0,       0.1,     0.5,    0.5,
3104         };
3105         float quad4[] = {
3106              320,       480,       0.1,     1.0,    0.0,    1.0,
3107              320,       240,       0.1,     1.0,    0.0,    1.0,
3108              640,       480,       0.1,     1.0,    0.0,    1.0,
3109              640,       240,       0.1,     1.0,    0.0,    1.0,
3110         };
3111         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3112                           0.0, 0.0, 0.0, 0.0,
3113                           0.0, 0.0, 0.0, 0.0,
3114                           0.0, 0.0, 0.0, 0.0};
3115
3116         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3117         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3118         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3119         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3120         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3121
3122         /* What happens with transforms enabled? */
3123         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3124         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3125         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3126         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3127
3128         /* What happens if 4 coords are used, but only 2 given ?*/
3129         mat[8] = 1.0;
3130         mat[13] = 1.0;
3131         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3133         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3134         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3135         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3136         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3137
3138         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3139          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3140          * due to the coords in the vertices. (turns out red, indeed)
3141          */
3142         memset(mat, 0, sizeof(mat));
3143         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3144         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3145         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3146         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3147         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3148         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3149         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3150         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3151
3152         hr = IDirect3DDevice9_EndScene(device);
3153         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3154     }
3155     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3156     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3157     color = getPixelColor(device, 160, 360);
3158     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3159     color = getPixelColor(device, 160, 120);
3160     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3161     color = getPixelColor(device, 480, 120);
3162     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3163     color = getPixelColor(device, 480, 360);
3164     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3165
3166     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3167     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3168
3169     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3170     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3171     hr = IDirect3DDevice9_BeginScene(device);
3172     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3173     if(SUCCEEDED(hr))
3174     {
3175         float quad1[] = {
3176             -1.0,      -1.0,       0.1,     0.8,    0.2,
3177             -1.0,       0.0,       0.1,     0.8,    0.2,
3178              0.0,      -1.0,       0.1,     0.8,    0.2,
3179              0.0,       0.0,       0.1,     0.8,    0.2,
3180         };
3181         float quad2[] = {
3182             -1.0,       0.0,       0.1,     0.5,    1.0,
3183             -1.0,       1.0,       0.1,     0.5,    1.0,
3184              0.0,       0.0,       0.1,     0.5,    1.0,
3185              0.0,       1.0,       0.1,     0.5,    1.0,
3186         };
3187         float quad3[] = {
3188              0.0,       0.0,       0.1,     0.5,    1.0,
3189              0.0,       1.0,       0.1,     0.5,    1.0,
3190              1.0,       0.0,       0.1,     0.5,    1.0,
3191              1.0,       1.0,       0.1,     0.5,    1.0,
3192         };
3193         float quad4[] = {
3194              0.0,      -1.0,       0.1,     0.8,    0.2,
3195              0.0,       0.0,       0.1,     0.8,    0.2,
3196              1.0,      -1.0,       0.1,     0.8,    0.2,
3197              1.0,       0.0,       0.1,     0.8,    0.2,
3198         };
3199         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3200                           0.0, 0.0, 0.0, 0.0,
3201                           0.0, 1.0, 0.0, 0.0,
3202                           0.0, 0.0, 0.0, 0.0};
3203
3204         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3205          */
3206         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3207         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3208         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3209         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3210
3211         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3212         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3213
3214         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3215          * it behaves like COUNT2 because normal textures require 2 coords
3216          */
3217         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3218         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3219         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3220         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3221
3222         /* Just to be sure, the same as quad2 above */
3223         memset(mat, 0, sizeof(mat));
3224         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3225         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3226         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3227         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3228         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3229         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3230
3231         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3232          * used? And what happens to the first?
3233          */
3234         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3235         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3236         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3237         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3238
3239         hr = IDirect3DDevice9_EndScene(device);
3240         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3241     }
3242     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3243     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3244     color = getPixelColor(device, 160, 360);
3245     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3246     color = getPixelColor(device, 160, 120);
3247     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3248     color = getPixelColor(device, 480, 120);
3249     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3250        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3251     color = getPixelColor(device, 480, 360);
3252     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3253        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3254
3255     IDirect3DTexture9_Release(texture);
3256
3257     /* Test projected textures, without any fancy matrices */
3258     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3259     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3260     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3261     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3262     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3263     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3264     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3265     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3266
3267     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3268     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3269     for(x = 0; x < 4; x++) {
3270         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3271     }
3272     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3273     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3274     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3275     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3276
3277     hr = IDirect3DDevice9_BeginScene(device);
3278     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3279     if(SUCCEEDED(hr))
3280     {
3281         const float proj_quads[] = {
3282            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3283             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3284            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3285             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3286            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3287             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3288            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3289             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3290         };
3291
3292         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3293         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3294         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3295         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3296
3297         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3298         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3300         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3301
3302         hr = IDirect3DDevice9_EndScene(device);
3303         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3304     }
3305
3306     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3307     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3308     IDirect3DTexture9_Release(texture);
3309
3310     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3311     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3312     color = getPixelColor(device, 158, 118);
3313     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3314     color = getPixelColor(device, 162, 118);
3315     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3316     color = getPixelColor(device, 158, 122);
3317     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3318     color = getPixelColor(device, 162, 122);
3319     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3320
3321     color = getPixelColor(device, 158, 178);
3322     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3323     color = getPixelColor(device, 162, 178);
3324     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3325     color = getPixelColor(device, 158, 182);
3326     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3327     color = getPixelColor(device, 162, 182);
3328     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3329
3330     color = getPixelColor(device, 318, 118);
3331     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3332     color = getPixelColor(device, 322, 118);
3333     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3334     color = getPixelColor(device, 318, 122);
3335     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3336     color = getPixelColor(device, 322, 122);
3337     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3338
3339     color = getPixelColor(device, 318, 178);
3340     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3341     color = getPixelColor(device, 322, 178);
3342     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3343     color = getPixelColor(device, 318, 182);
3344     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3345     color = getPixelColor(device, 322, 182);
3346     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3347
3348     color = getPixelColor(device, 238, 298);
3349     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3350     color = getPixelColor(device, 242, 298);
3351     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3352     color = getPixelColor(device, 238, 302);
3353     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3354     color = getPixelColor(device, 242, 302);
3355     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3356
3357     color = getPixelColor(device, 238, 388);
3358     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3359     color = getPixelColor(device, 242, 388);
3360     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3361     color = getPixelColor(device, 238, 392);
3362     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3363     color = getPixelColor(device, 242, 392);
3364     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3365
3366     color = getPixelColor(device, 478, 298);
3367     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3368     color = getPixelColor(device, 482, 298);
3369     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3370     color = getPixelColor(device, 478, 302);
3371     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3372     color = getPixelColor(device, 482, 302);
3373     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3374
3375     color = getPixelColor(device, 478, 388);
3376     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3377     color = getPixelColor(device, 482, 388);
3378     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3379     color = getPixelColor(device, 478, 392);
3380     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3381     color = getPixelColor(device, 482, 392);
3382     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3383
3384     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3386     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3387      * Thus watch out if sampling from texels between 0 and 1.
3388      */
3389     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3390     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3391        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3392     if(!volume) {
3393         skip("Failed to create a volume texture\n");
3394         goto out;
3395     }
3396
3397     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3398     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3399     for(z = 0; z < 32; z++) {
3400         for(y = 0; y < 32; y++) {
3401             for(x = 0; x < 32; x++) {
3402                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3403                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3404                 float r_f = (float) x / 31.0;
3405                 float g_f = (float) y / 31.0;
3406                 float b_f = (float) z / 31.0;
3407
3408                 if(fmt == D3DFMT_A16B16G16R16) {
3409                     unsigned short *mem_s = mem;
3410                     mem_s[0]  = r_f * 65535.0;
3411                     mem_s[1]  = g_f * 65535.0;
3412                     mem_s[2]  = b_f * 65535.0;
3413                     mem_s[3]  = 65535;
3414                 } else {
3415                     unsigned char *mem_c = mem;
3416                     mem_c[0]  = b_f * 255.0;
3417                     mem_c[1]  = g_f * 255.0;
3418                     mem_c[2]  = r_f * 255.0;
3419                     mem_c[3]  = 255;
3420                 }
3421             }
3422         }
3423     }
3424     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3425     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3426
3427     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3428     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3429
3430     hr = IDirect3DDevice9_BeginScene(device);
3431     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3432     if(SUCCEEDED(hr))
3433     {
3434         float quad1[] = {
3435             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3436             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3437              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3438              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3439         };
3440         float quad2[] = {
3441             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3442             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3443              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3444              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3445         };
3446         float quad3[] = {
3447              0.0,       0.0,       0.1,     0.0,    0.0,
3448              0.0,       1.0,       0.1,     0.0,    0.0,
3449              1.0,       0.0,       0.1,     0.0,    0.0,
3450              1.0,       1.0,       0.1,     0.0,    0.0
3451         };
3452         float quad4[] = {
3453              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3454              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3455              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3456              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3457         };
3458         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3459                          0.0, 0.0, 1.0, 0.0,
3460                          0.0, 1.0, 0.0, 0.0,
3461                          0.0, 0.0, 0.0, 1.0};
3462         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3463         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3464
3465         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3466          * values
3467          */
3468         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3469         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3470         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3471         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3472         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3473         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3474
3475         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3476          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3477          * otherwise the w will be missing(blue).
3478          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3479          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3480          */
3481         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3482         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3483         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3484         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3485
3486         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3487         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3488         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3489         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3490         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3491         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3492         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3493         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3494         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3495
3496         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3497          * disable. ATI extends it up to the amount of values needed for the volume texture
3498          */
3499         memset(mat, 0, sizeof(mat));
3500         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3501         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3502         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3503         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3504         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3505         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3507         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3508
3509         hr = IDirect3DDevice9_EndScene(device);
3510         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3511     }
3512     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3513     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3514
3515     color = getPixelColor(device, 160, 360);
3516     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3517     color = getPixelColor(device, 160, 120);
3518     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3519        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3520     color = getPixelColor(device, 480, 120);
3521     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3522     color = getPixelColor(device, 480, 360);
3523     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3524
3525     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3526     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3527     hr = IDirect3DDevice9_BeginScene(device);
3528     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3529     if(SUCCEEDED(hr))
3530     {
3531         float quad1[] = {
3532             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3533             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3534              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3535              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3536         };
3537         float quad2[] = {
3538             -1.0,       0.0,       0.1,
3539             -1.0,       1.0,       0.1,
3540              0.0,       0.0,       0.1,
3541              0.0,       1.0,       0.1,
3542         };
3543         float quad3[] = {
3544              0.0,       0.0,       0.1,     1.0,
3545              0.0,       1.0,       0.1,     1.0,
3546              1.0,       0.0,       0.1,     1.0,
3547              1.0,       1.0,       0.1,     1.0
3548         };
3549         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3550                            0.0, 0.0, 0.0, 0.0,
3551                            0.0, 0.0, 0.0, 0.0,
3552                            0.0, 1.0, 0.0, 0.0};
3553         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3554                            1.0, 0.0, 0.0, 0.0,
3555                            0.0, 1.0, 0.0, 0.0,
3556                            0.0, 0.0, 1.0, 0.0};
3557         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3558         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3559
3560         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3561          */
3562         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3563         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3564         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3565         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3566         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3567         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3568
3569         /* None passed */
3570         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3573         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3574         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3575         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3576
3577         /* 4 used, 1 passed */
3578         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3579         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3580         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3581         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3582         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3583         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3584
3585         hr = IDirect3DDevice9_EndScene(device);
3586         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3587     }
3588     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3589     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3590     color = getPixelColor(device, 160, 360);
3591     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3592     color = getPixelColor(device, 160, 120);
3593     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3594     color = getPixelColor(device, 480, 120);
3595     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3596     /* Quad4: unused */
3597
3598     IDirect3DVolumeTexture9_Release(volume);
3599
3600     out:
3601     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3602     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3603     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3604     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3605     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3606     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3607     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3608     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3609     IDirect3DVertexDeclaration9_Release(decl);
3610     IDirect3DVertexDeclaration9_Release(decl2);
3611     IDirect3DVertexDeclaration9_Release(decl3);
3612 }
3613
3614 static void texdepth_test(IDirect3DDevice9 *device)
3615 {
3616     IDirect3DPixelShader9 *shader;
3617     HRESULT hr;
3618     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3619     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3620     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3621     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3622     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3623     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3624     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3625     DWORD shader_code[] = {
3626         0xffff0104,                                                                 /* ps_1_4               */
3627         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3628         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3629         0x0000fffd,                                                                 /* phase                */
3630         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3631         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3632         0x0000ffff                                                                  /* end                  */
3633     };
3634     DWORD color;
3635     float vertex[] = {
3636        -1.0,   -1.0,    0.0,
3637         1.0,   -1.0,    1.0,
3638        -1.0,    1.0,    0.0,
3639         1.0,    1.0,    1.0
3640     };
3641
3642     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3644
3645     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3646     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3648     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3650     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3652     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3653     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3654
3655     /* Fill the depth buffer with a gradient */
3656     hr = IDirect3DDevice9_BeginScene(device);
3657     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3658     if(SUCCEEDED(hr))
3659     {
3660         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3661         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3662         hr = IDirect3DDevice9_EndScene(device);
3663         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3664     }
3665
3666     /* Now perform the actual tests. Same geometry, but with the shader */
3667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3668     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3669     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3670     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3671     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3672     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3673
3674     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3675     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3676     hr = IDirect3DDevice9_BeginScene(device);
3677     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3678     if(SUCCEEDED(hr))
3679     {
3680         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3681         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3682
3683         hr = IDirect3DDevice9_EndScene(device);
3684         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3685     }
3686
3687     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3688     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3689     color = getPixelColor(device, 158, 240);
3690     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3691     color = getPixelColor(device, 162, 240);
3692     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3693
3694     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3695
3696     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3697     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3698     hr = IDirect3DDevice9_BeginScene(device);
3699     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3700     if(SUCCEEDED(hr))
3701     {
3702         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3703         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3704
3705         hr = IDirect3DDevice9_EndScene(device);
3706         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3707     }
3708
3709     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3710     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3711     color = getPixelColor(device, 318, 240);
3712     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3713     color = getPixelColor(device, 322, 240);
3714     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3715
3716     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3717
3718     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3720     hr = IDirect3DDevice9_BeginScene(device);
3721     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3722     if(SUCCEEDED(hr))
3723     {
3724         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3725         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3726
3727         hr = IDirect3DDevice9_EndScene(device);
3728         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3729     }
3730     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3732
3733     color = getPixelColor(device, 1, 240);
3734     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3735
3736     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3737
3738     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3739     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3740     hr = IDirect3DDevice9_BeginScene(device);
3741     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3742     if(SUCCEEDED(hr))
3743     {
3744         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3745         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3746
3747         hr = IDirect3DDevice9_EndScene(device);
3748         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3749     }
3750     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3751     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3752     color = getPixelColor(device, 318, 240);
3753     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3754     color = getPixelColor(device, 322, 240);
3755     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3756
3757     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3758
3759     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3761     hr = IDirect3DDevice9_BeginScene(device);
3762     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3763     if(SUCCEEDED(hr))
3764     {
3765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3766         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3767
3768         hr = IDirect3DDevice9_EndScene(device);
3769         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3770     }
3771     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3772     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3773
3774     color = getPixelColor(device, 1, 240);
3775     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3776
3777     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3778
3779     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3781     hr = IDirect3DDevice9_BeginScene(device);
3782     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3783     if(SUCCEEDED(hr))
3784     {
3785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3786         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3787
3788         hr = IDirect3DDevice9_EndScene(device);
3789         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3790     }
3791     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3792     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3793
3794     color = getPixelColor(device, 638, 240);
3795     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3796
3797     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3798
3799     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3801     hr = IDirect3DDevice9_BeginScene(device);
3802     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3803     if(SUCCEEDED(hr))
3804     {
3805         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3806         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3807
3808         hr = IDirect3DDevice9_EndScene(device);
3809         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3810     }
3811     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3812     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3813
3814     color = getPixelColor(device, 638, 240);
3815     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3816
3817     /* Cleanup */
3818     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3819     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3820     IDirect3DPixelShader9_Release(shader);
3821
3822     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3823     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3824     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3825     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3826 }
3827
3828 static void texkill_test(IDirect3DDevice9 *device)
3829 {
3830     IDirect3DPixelShader9 *shader;
3831     HRESULT hr;
3832     DWORD color;
3833
3834     const float vertex[] = {
3835     /*                          bottom  top    right    left */
3836         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3837          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3838         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3839          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3840     };
3841
3842     DWORD shader_code_11[] = {
3843     0xffff0101,                                                             /* ps_1_1                     */
3844     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3845     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3846     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3847     0x0000ffff                                                              /* end                        */
3848     };
3849     DWORD shader_code_20[] = {
3850     0xffff0200,                                                             /* ps_2_0                     */
3851     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3852     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3853     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3854     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3855     0x0000ffff                                                              /* end                        */
3856     };
3857
3858     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3859     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3860     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3861     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3862
3863     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3864     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3865     hr = IDirect3DDevice9_BeginScene(device);
3866     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3867     if(SUCCEEDED(hr))
3868     {
3869         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3870         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3872         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3873         hr = IDirect3DDevice9_EndScene(device);
3874         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3875     }
3876     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3877     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3878     color = getPixelColor(device, 63, 46);
3879     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3880     color = getPixelColor(device, 66, 46);
3881     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3882     color = getPixelColor(device, 63, 49);
3883     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3884     color = getPixelColor(device, 66, 49);
3885     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3886
3887     color = getPixelColor(device, 578, 46);
3888     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3889     color = getPixelColor(device, 575, 46);
3890     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3891     color = getPixelColor(device, 578, 49);
3892     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3893     color = getPixelColor(device, 575, 49);
3894     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3895
3896     color = getPixelColor(device, 63, 430);
3897     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3898     color = getPixelColor(device, 63, 433);
3899     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3900     color = getPixelColor(device, 66, 433);
3901     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3902     color = getPixelColor(device, 66, 430);
3903     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3904
3905     color = getPixelColor(device, 578, 430);
3906     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3907     color = getPixelColor(device, 578, 433);
3908     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3909     color = getPixelColor(device, 575, 433);
3910     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3911     color = getPixelColor(device, 575, 430);
3912     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3913
3914     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3915     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3916     IDirect3DPixelShader9_Release(shader);
3917
3918     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3919     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3920     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3921     if(FAILED(hr)) {
3922         skip("Failed to create 2.0 test shader, most likely not supported\n");
3923         return;
3924     }
3925
3926     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3927     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3928     hr = IDirect3DDevice9_BeginScene(device);
3929     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3930     if(SUCCEEDED(hr))
3931     {
3932         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3933         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3934         hr = IDirect3DDevice9_EndScene(device);
3935         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3936     }
3937     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3938
3939     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3940     color = getPixelColor(device, 63, 46);
3941     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3942     color = getPixelColor(device, 66, 46);
3943     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3944     color = getPixelColor(device, 63, 49);
3945     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3946     color = getPixelColor(device, 66, 49);
3947     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3948
3949     color = getPixelColor(device, 578, 46);
3950     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3951     color = getPixelColor(device, 575, 46);
3952     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3953     color = getPixelColor(device, 578, 49);
3954     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3955     color = getPixelColor(device, 575, 49);
3956     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3957
3958     color = getPixelColor(device, 63, 430);
3959     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3960     color = getPixelColor(device, 63, 433);
3961     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3962     color = getPixelColor(device, 66, 433);
3963     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3964     color = getPixelColor(device, 66, 430);
3965     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3966
3967     color = getPixelColor(device, 578, 430);
3968     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3969     color = getPixelColor(device, 578, 433);
3970     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3971     color = getPixelColor(device, 575, 433);
3972     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3973     color = getPixelColor(device, 575, 430);
3974     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3975
3976     /* Cleanup */
3977     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3978     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3979     IDirect3DPixelShader9_Release(shader);
3980 }
3981
3982 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3983 {
3984     IDirect3D9 *d3d9;
3985     HRESULT hr;
3986     IDirect3DTexture9 *texture;
3987     IDirect3DPixelShader9 *shader;
3988     IDirect3DPixelShader9 *shader2;
3989     D3DLOCKED_RECT lr;
3990     DWORD color;
3991     DWORD shader_code[] = {
3992         0xffff0101,                             /* ps_1_1       */
3993         0x00000042, 0xb00f0000,                 /* tex t0       */
3994         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3995         0x0000ffff                              /* end          */
3996     };
3997     DWORD shader_code2[] = {
3998         0xffff0101,                             /* ps_1_1       */
3999         0x00000042, 0xb00f0000,                 /* tex t0       */
4000         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4001         0x0000ffff                              /* end          */
4002     };
4003
4004     float quad[] = {
4005        -1.0,   -1.0,   0.1,     0.5,    0.5,
4006         1.0,   -1.0,   0.1,     0.5,    0.5,
4007        -1.0,    1.0,   0.1,     0.5,    0.5,
4008         1.0,    1.0,   0.1,     0.5,    0.5,
4009     };
4010
4011     memset(&lr, 0, sizeof(lr));
4012     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4013     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4014                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4015     IDirect3D9_Release(d3d9);
4016     if(FAILED(hr)) {
4017         skip("No D3DFMT_X8L8V8U8 support\n");
4018     };
4019
4020     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4022
4023     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4024     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4025     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4026     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4027     *((DWORD *) lr.pBits) = 0x11ca3141;
4028     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4029     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4030
4031     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4032     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4033     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4034     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4035
4036     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4037     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4038     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4040     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4041     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4042
4043     hr = IDirect3DDevice9_BeginScene(device);
4044     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4045     if(SUCCEEDED(hr))
4046     {
4047         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4048         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4049
4050         hr = IDirect3DDevice9_EndScene(device);
4051         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4052     }
4053     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4054     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4055     color = getPixelColor(device, 578, 430);
4056     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4057        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4058
4059     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4060     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4061     hr = IDirect3DDevice9_BeginScene(device);
4062     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4063     if(SUCCEEDED(hr))
4064     {
4065         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4066         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4067
4068         hr = IDirect3DDevice9_EndScene(device);
4069         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4070     }
4071     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4072     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4073     color = getPixelColor(device, 578, 430);
4074     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4075
4076     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4077     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4078     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4079     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4080     IDirect3DPixelShader9_Release(shader);
4081     IDirect3DPixelShader9_Release(shader2);
4082     IDirect3DTexture9_Release(texture);
4083 }
4084
4085 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4086 {
4087     HRESULT hr;
4088     IDirect3D9 *d3d;
4089     IDirect3DTexture9 *texture = NULL;
4090     IDirect3DSurface9 *surface;
4091     DWORD color;
4092     const RECT r1 = {256, 256, 512, 512};
4093     const RECT r2 = {512, 256, 768, 512};
4094     const RECT r3 = {256, 512, 512, 768};
4095     const RECT r4 = {512, 512, 768, 768};
4096     unsigned int x, y;
4097     D3DLOCKED_RECT lr;
4098     memset(&lr, 0, sizeof(lr));
4099
4100     IDirect3DDevice9_GetDirect3D(device, &d3d);
4101     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4102        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4103         skip("No autogenmipmap support\n");
4104         IDirect3D9_Release(d3d);
4105         return;
4106     }
4107     IDirect3D9_Release(d3d);
4108
4109     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4110     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4111
4112     /* Make the mipmap big, so that a smaller mipmap is used
4113      */
4114     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4115                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4116     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4117
4118     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4119     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4120     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4121     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4122     for(y = 0; y < 1024; y++) {
4123         for(x = 0; x < 1024; x++) {
4124             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4125             POINT pt;
4126
4127             pt.x = x;
4128             pt.y = y;
4129             if(PtInRect(&r1, pt)) {
4130                 *dst = 0xffff0000;
4131             } else if(PtInRect(&r2, pt)) {
4132                 *dst = 0xff00ff00;
4133             } else if(PtInRect(&r3, pt)) {
4134                 *dst = 0xff0000ff;
4135             } else if(PtInRect(&r4, pt)) {
4136                 *dst = 0xff000000;
4137             } else {
4138                 *dst = 0xffffffff;
4139             }
4140         }
4141     }
4142     hr = IDirect3DSurface9_UnlockRect(surface);
4143     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4144     IDirect3DSurface9_Release(surface);
4145
4146     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4147     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4148     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4149     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4150
4151     hr = IDirect3DDevice9_BeginScene(device);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4153     if(SUCCEEDED(hr)) {
4154         const float quad[] =  {
4155            -0.5,   -0.5,    0.1,    0.0,    0.0,
4156            -0.5,    0.5,    0.1,    0.0,    1.0,
4157             0.5,   -0.5,    0.1,    1.0,    0.0,
4158             0.5,    0.5,    0.1,    1.0,    1.0
4159         };
4160
4161         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4162         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4163         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4164         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4165         hr = IDirect3DDevice9_EndScene(device);
4166         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4167     }
4168     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4169     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4170     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4172     IDirect3DTexture9_Release(texture);
4173
4174     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4175     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4176     color = getPixelColor(device, 200, 200);
4177     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4178     color = getPixelColor(device, 280, 200);
4179     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4180     color = getPixelColor(device, 360, 200);
4181     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4182     color = getPixelColor(device, 440, 200);
4183     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4184     color = getPixelColor(device, 200, 270);
4185     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4186     color = getPixelColor(device, 280, 270);
4187     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4188     color = getPixelColor(device, 360, 270);
4189     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4190     color = getPixelColor(device, 440, 270);
4191     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4192 }
4193
4194 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4195 {
4196     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4197     IDirect3DVertexDeclaration9 *decl;
4198     HRESULT hr;
4199     DWORD color;
4200     DWORD shader_code_11[] =  {
4201         0xfffe0101,                                         /* vs_1_1           */
4202         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4203         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4204         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4205         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4206         0x0000ffff                                          /* end              */
4207     };
4208     DWORD shader_code_11_2[] =  {
4209         0xfffe0101,                                         /* vs_1_1           */
4210         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4211         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4212         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4213         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4214         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4215         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4216         0x0000ffff                                          /* end              */
4217     };
4218     DWORD shader_code_20[] =  {
4219         0xfffe0200,                                         /* vs_2_0           */
4220         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4221         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4222         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4223         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4224         0x0000ffff                                          /* end              */
4225     };
4226     DWORD shader_code_20_2[] =  {
4227         0xfffe0200,                                         /* vs_2_0           */
4228         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4229         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4230         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4231         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4232         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4233         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4234         0x0000ffff                                          /* end              */
4235     };
4236     static const D3DVERTEXELEMENT9 decl_elements[] = {
4237         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4238         D3DDECL_END()
4239     };
4240     float quad1[] = {
4241         -1.0,   -1.0,   0.1,
4242          0.0,   -1.0,   0.1,
4243         -1.0,    0.0,   0.1,
4244          0.0,    0.0,   0.1
4245     };
4246     float quad2[] = {
4247          0.0,   -1.0,   0.1,
4248          1.0,   -1.0,   0.1,
4249          0.0,    0.0,   0.1,
4250          1.0,    0.0,   0.1
4251     };
4252     float quad3[] = {
4253          0.0,    0.0,   0.1,
4254          1.0,    0.0,   0.1,
4255          0.0,    1.0,   0.1,
4256          1.0,    1.0,   0.1
4257     };
4258     float quad4[] = {
4259         -1.0,    0.0,   0.1,
4260          0.0,    0.0,   0.1,
4261         -1.0,    1.0,   0.1,
4262          0.0,    1.0,   0.1
4263     };
4264     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4265     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4266
4267     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4268     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4269
4270     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4271     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4272     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4273     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4274     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4275     if(FAILED(hr)) shader_20 = NULL;
4276     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4277     if(FAILED(hr)) shader_20_2 = NULL;
4278     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4279     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4280
4281     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4282     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4283     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4284     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4285     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4286     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4287
4288     hr = IDirect3DDevice9_BeginScene(device);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4290     if(SUCCEEDED(hr))
4291     {
4292         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4293         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4294         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4295         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4296
4297         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4298         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4300         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4301
4302         if(shader_20) {
4303             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4304             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4305             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4306             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4307         }
4308
4309         if(shader_20_2) {
4310             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4311             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4312             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4313             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4314         }
4315
4316         hr = IDirect3DDevice9_EndScene(device);
4317         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4318     }
4319     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4320     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4321
4322     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4323     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4324     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4325     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4326
4327     color = getPixelColor(device, 160, 360);
4328     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4330     color = getPixelColor(device, 480, 360);
4331     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4332        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4333     if(shader_20) {
4334         color = getPixelColor(device, 160, 120);
4335         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4336            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4337     }
4338     if(shader_20_2) {
4339         color = getPixelColor(device, 480, 120);
4340         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4341            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4342     }
4343
4344     IDirect3DVertexDeclaration9_Release(decl);
4345     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4346     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4347     IDirect3DVertexShader9_Release(shader_11_2);
4348     IDirect3DVertexShader9_Release(shader_11);
4349 }
4350
4351 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4352 {
4353     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4354     HRESULT hr;
4355     DWORD color;
4356     DWORD shader_code_11[] =  {
4357         0xffff0101,                                         /* ps_1_1           */
4358         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4359         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4360         0x0000ffff                                          /* end              */
4361     };
4362     DWORD shader_code_12[] =  {
4363         0xffff0102,                                         /* ps_1_2           */
4364         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4365         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4366         0x0000ffff                                          /* end              */
4367     };
4368     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4369      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4370      * During development of this test, 1.3 shaders were verified too
4371      */
4372     DWORD shader_code_14[] =  {
4373         0xffff0104,                                         /* ps_1_4           */
4374         /* Try to make one constant local. It gets clamped too, although the binary contains
4375          * the bigger numbers
4376          */
4377         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4378         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4379         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4380         0x0000ffff                                          /* end              */
4381     };
4382     DWORD shader_code_20[] =  {
4383         0xffff0200,                                         /* ps_2_0           */
4384         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4385         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4386         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4387         0x0000ffff                                          /* end              */
4388     };
4389     float quad1[] = {
4390         -1.0,   -1.0,   0.1,
4391          0.0,   -1.0,   0.1,
4392         -1.0,    0.0,   0.1,
4393          0.0,    0.0,   0.1
4394     };
4395     float quad2[] = {
4396          0.0,   -1.0,   0.1,
4397          1.0,   -1.0,   0.1,
4398          0.0,    0.0,   0.1,
4399          1.0,    0.0,   0.1
4400     };
4401     float quad3[] = {
4402          0.0,    0.0,   0.1,
4403          1.0,    0.0,   0.1,
4404          0.0,    1.0,   0.1,
4405          1.0,    1.0,   0.1
4406     };
4407     float quad4[] = {
4408         -1.0,    0.0,   0.1,
4409          0.0,    0.0,   0.1,
4410         -1.0,    1.0,   0.1,
4411          0.0,    1.0,   0.1
4412     };
4413     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4414     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4415
4416     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4417     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4418
4419     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4420     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4421     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4422     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4423     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4424     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4425     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4426     if(FAILED(hr)) shader_20 = NULL;
4427
4428     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4429     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4430     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4431     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4432     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4433     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4434
4435     hr = IDirect3DDevice9_BeginScene(device);
4436     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4437     if(SUCCEEDED(hr))
4438     {
4439         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4440         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4442         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4443
4444         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4445         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4447         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4448
4449         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4450         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4451         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4452         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4453
4454         if(shader_20) {
4455             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4456             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4457             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4458             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4459         }
4460
4461         hr = IDirect3DDevice9_EndScene(device);
4462         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4463     }
4464     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4465     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4466
4467     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4468     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4469
4470     color = getPixelColor(device, 160, 360);
4471     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4472        "quad 1 has color %08x, expected 0x00808000\n", color);
4473     color = getPixelColor(device, 480, 360);
4474     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4475        "quad 2 has color %08x, expected 0x00808000\n", color);
4476     color = getPixelColor(device, 480, 120);
4477     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4478        "quad 3 has color %08x, expected 0x00808000\n", color);
4479     if(shader_20) {
4480         color = getPixelColor(device, 160, 120);
4481         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4482            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4483     }
4484
4485     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4486     IDirect3DPixelShader9_Release(shader_14);
4487     IDirect3DPixelShader9_Release(shader_12);
4488     IDirect3DPixelShader9_Release(shader_11);
4489 }
4490
4491 static void dp2add_ps_test(IDirect3DDevice9 *device)
4492 {
4493     IDirect3DPixelShader9 *shader_dp2add = NULL;
4494     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4495     HRESULT hr;
4496     DWORD color;
4497
4498     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4499      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4500      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4501      * r0 first.
4502      * The result here for the r,g,b components should be roughly 0.5:
4503      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4504     static const DWORD shader_code_dp2add[] =  {
4505         0xffff0200,                                                             /* ps_2_0                       */
4506         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4507
4508         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4509         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4510
4511         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4512         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4513         0x0000ffff                                                              /* end                          */
4514     };
4515
4516     /* Test the _sat modifier, too.  Result here should be:
4517      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4518      *      _SAT: ==> 1.0
4519      *   ADD: (1.0 + -0.5) = 0.5
4520      */
4521     static const DWORD shader_code_dp2add_sat[] =  {
4522         0xffff0200,                                                             /* ps_2_0                           */
4523         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4524
4525         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4526         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4527         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4528
4529         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4530         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4531         0x0000ffff                                                              /* end                              */
4532     };
4533
4534     const float quad[] = {
4535         -1.0,   -1.0,   0.1,
4536          1.0,   -1.0,   0.1,
4537         -1.0,    1.0,   0.1,
4538          1.0,    1.0,   0.1
4539     };
4540
4541
4542     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4543     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4544
4545     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4546     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4547
4548     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4549     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4550
4551     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4552     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4553
4554     if (shader_dp2add) {
4555
4556         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4557         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4558
4559         hr = IDirect3DDevice9_BeginScene(device);
4560         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", 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 %08x\n", hr);
4568         }
4569         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4570         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", 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);
4576     } else {
4577         skip("dp2add shader creation failed\n");
4578     }
4579
4580     if (shader_dp2add_sat) {
4581
4582         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4583         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4584
4585         hr = IDirect3DDevice9_BeginScene(device);
4586         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4587         if(SUCCEEDED(hr))
4588         {
4589             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4590             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4591
4592             hr = IDirect3DDevice9_EndScene(device);
4593             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4594         }
4595         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4596         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4597
4598         color = getPixelColor(device, 360, 240);
4599         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4600
4601         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4602     } else {
4603         skip("dp2add shader creation failed\n");
4604     }
4605
4606     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4607     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4608 }
4609
4610 static void cnd_test(IDirect3DDevice9 *device)
4611 {
4612     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4613     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4614     HRESULT hr;
4615     DWORD color;
4616     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4617      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4618      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4619      */
4620     DWORD shader_code_11[] =  {
4621         0xffff0101,                                                                 /* ps_1_1               */
4622         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4623         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4624         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4625         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4626         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4627         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4628         0x0000ffff                                                                  /* end                  */
4629     };
4630     DWORD shader_code_12[] =  {
4631         0xffff0102,                                                                 /* ps_1_2               */
4632         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4633         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4634         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4635         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4636         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4637         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4638         0x0000ffff                                                                  /* end                  */
4639     };
4640     DWORD shader_code_13[] =  {
4641         0xffff0103,                                                                 /* ps_1_3               */
4642         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4643         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4644         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4645         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4646         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4647         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4648         0x0000ffff                                                                  /* end                  */
4649     };
4650     DWORD shader_code_14[] =  {
4651         0xffff0104,                                                                 /* ps_1_3               */
4652         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4653         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4654         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4655         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4656         0x0000ffff                                                                  /* end                  */
4657     };
4658
4659     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4660      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4661      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4662      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4663      * native CreatePixelShader returns an error.
4664      *
4665      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4666      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4667      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4668      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4669      */
4670     DWORD shader_code_11_coissue[] =  {
4671         0xffff0101,                                                             /* ps_1_1                   */
4672         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4673         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4674         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4675         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4676         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4677         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4678         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4679         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4680         /* 0x40000000 = D3DSI_COISSUE */
4681         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4682         0x0000ffff                                                              /* end                      */
4683     };
4684     DWORD shader_code_12_coissue[] =  {
4685         0xffff0102,                                                             /* ps_1_2                   */
4686         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4687         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4688         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4689         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4690         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4691         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4692         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4693         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4694         /* 0x40000000 = D3DSI_COISSUE */
4695         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4696         0x0000ffff                                                              /* end                      */
4697     };
4698     DWORD shader_code_13_coissue[] =  {
4699         0xffff0103,                                                             /* ps_1_3                   */
4700         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4701         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4702         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4703         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4704         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4705         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4706         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4707         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4708         /* 0x40000000 = D3DSI_COISSUE */
4709         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4710         0x0000ffff                                                              /* end                      */
4711     };
4712     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4713      * compare against 0.5
4714      */
4715     DWORD shader_code_14_coissue[] =  {
4716         0xffff0104,                                                             /* ps_1_4                   */
4717         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4718         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4719         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4720         /* 0x40000000 = D3DSI_COISSUE */
4721         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4722         0x0000ffff                                                              /* end                      */
4723     };
4724     float quad1[] = {
4725         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4726          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4727         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4728          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4729     };
4730     float quad2[] = {
4731          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4732          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4733          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4734          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4735     };
4736     float quad3[] = {
4737          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4738          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4739          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4740          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4741     };
4742     float quad4[] = {
4743         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4744          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4745         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4746          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4747     };
4748     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4749     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4750     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4751     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4752
4753     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4754     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4755
4756     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4758     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4760     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4761     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4762     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4763     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4764     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4765     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4766     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4767     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4768     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4769     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4770     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4771     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4772
4773     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4774     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4775     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4776     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4777     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4778     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4779
4780     hr = IDirect3DDevice9_BeginScene(device);
4781     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4782     if(SUCCEEDED(hr))
4783     {
4784         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4785         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4786         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4787         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4788
4789         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4790         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4792         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4793
4794         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4795         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4797         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4798
4799         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4800         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4803
4804         hr = IDirect3DDevice9_EndScene(device);
4805         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4806     }
4807     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4808     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4809
4810     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4811     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4812
4813     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4814     color = getPixelColor(device, 158, 118);
4815     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4816     color = getPixelColor(device, 162, 118);
4817     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4818     color = getPixelColor(device, 158, 122);
4819     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4820     color = getPixelColor(device, 162, 122);
4821     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4822
4823     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4824     color = getPixelColor(device, 158, 358);
4825     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4826     color = getPixelColor(device, 162, 358);
4827     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4828         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4829     color = getPixelColor(device, 158, 362);
4830     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4831     color = getPixelColor(device, 162, 362);
4832     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4833         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4834
4835     /* 1.2 shader */
4836     color = getPixelColor(device, 478, 358);
4837     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4838     color = getPixelColor(device, 482, 358);
4839     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4840         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4841     color = getPixelColor(device, 478, 362);
4842     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4843     color = getPixelColor(device, 482, 362);
4844     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4845         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4846
4847     /* 1.3 shader */
4848     color = getPixelColor(device, 478, 118);
4849     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4850     color = getPixelColor(device, 482, 118);
4851     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4852         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4853     color = getPixelColor(device, 478, 122);
4854     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4855     color = getPixelColor(device, 482, 122);
4856     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4857         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4858
4859     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4860     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4861     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4862     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4863     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4864     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4865
4866     hr = IDirect3DDevice9_BeginScene(device);
4867     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4868     if(SUCCEEDED(hr))
4869     {
4870         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4871         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4872         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4873         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4874
4875         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4876         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4877         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4878         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4879
4880         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4881         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4882         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4883         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4884
4885         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4886         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4887         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4888         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4889
4890         hr = IDirect3DDevice9_EndScene(device);
4891         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4892     }
4893     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4894     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4895
4896     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4897     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4898
4899     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4900      * that we swapped the values in c1 and c2 to make the other tests return some color
4901      */
4902     color = getPixelColor(device, 158, 118);
4903     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4904     color = getPixelColor(device, 162, 118);
4905     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4906     color = getPixelColor(device, 158, 122);
4907     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4908     color = getPixelColor(device, 162, 122);
4909     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4910
4911     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4912     color = getPixelColor(device, 158, 358);
4913     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4914         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4915     color = getPixelColor(device, 162, 358);
4916     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4917         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4918     color = getPixelColor(device, 158, 362);
4919     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4920         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4921     color = getPixelColor(device, 162, 362);
4922     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4923         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4924
4925     /* 1.2 shader */
4926     color = getPixelColor(device, 478, 358);
4927     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4928         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4929     color = getPixelColor(device, 482, 358);
4930     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4931         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4932     color = getPixelColor(device, 478, 362);
4933     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4934         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4935     color = getPixelColor(device, 482, 362);
4936     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4937         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4938
4939     /* 1.3 shader */
4940     color = getPixelColor(device, 478, 118);
4941     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4942         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4943     color = getPixelColor(device, 482, 118);
4944     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4945         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4946     color = getPixelColor(device, 478, 122);
4947     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4948         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4949     color = getPixelColor(device, 482, 122);
4950     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4951         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4952
4953     IDirect3DPixelShader9_Release(shader_14_coissue);
4954     IDirect3DPixelShader9_Release(shader_13_coissue);
4955     IDirect3DPixelShader9_Release(shader_12_coissue);
4956     IDirect3DPixelShader9_Release(shader_11_coissue);
4957     IDirect3DPixelShader9_Release(shader_14);
4958     IDirect3DPixelShader9_Release(shader_13);
4959     IDirect3DPixelShader9_Release(shader_12);
4960     IDirect3DPixelShader9_Release(shader_11);
4961 }
4962
4963 static void nested_loop_test(IDirect3DDevice9 *device) {
4964     const DWORD shader_code[] = {
4965         0xffff0300,                                                             /* ps_3_0               */
4966         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4967         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4968         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4969         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4970         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4971         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4972         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4973         0x0000001d,                                                             /* endloop              */
4974         0x0000001d,                                                             /* endloop              */
4975         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4976         0x0000ffff                                                              /* end                  */
4977     };
4978     IDirect3DPixelShader9 *shader;
4979     HRESULT hr;
4980     DWORD color;
4981     const float quad[] = {
4982         -1.0,   -1.0,   0.1,
4983          1.0,   -1.0,   0.1,
4984         -1.0,    1.0,   0.1,
4985          1.0,    1.0,   0.1
4986     };
4987
4988     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4989     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
4990     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4991     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
4992     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4993     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4994     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4995     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4996
4997     hr = IDirect3DDevice9_BeginScene(device);
4998     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4999     if(SUCCEEDED(hr))
5000     {
5001         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5002         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5003         hr = IDirect3DDevice9_EndScene(device);
5004         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5005     }
5006     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5007     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5008
5009     color = getPixelColor(device, 360, 240);
5010     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5011        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5012
5013     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5014     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5015     IDirect3DPixelShader9_Release(shader);
5016 }
5017
5018 struct varying_test_struct
5019 {
5020     const DWORD             *shader_code;
5021     IDirect3DPixelShader9   *shader;
5022     DWORD                   color, color_rhw;
5023     const char              *name;
5024     BOOL                    todo, todo_rhw;
5025 };
5026
5027 struct hugeVertex
5028 {
5029     float pos_x,        pos_y,      pos_z,      rhw;
5030     float weight_1,     weight_2,   weight_3,   weight_4;
5031     float index_1,      index_2,    index_3,    index_4;
5032     float normal_1,     normal_2,   normal_3,   normal_4;
5033     float fog_1,        fog_2,      fog_3,      fog_4;
5034     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5035     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5036     float binormal_1,   binormal_2, binormal_3, binormal_4;
5037     float depth_1,      depth_2,    depth_3,    depth_4;
5038     DWORD diffuse, specular;
5039 };
5040
5041 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5042     /* dcl_position: fails to compile */
5043     const DWORD blendweight_code[] = {
5044         0xffff0300,                             /* ps_3_0                   */
5045         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5046         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5047         0x0000ffff                              /* end                      */
5048     };
5049     const DWORD blendindices_code[] = {
5050         0xffff0300,                             /* ps_3_0                   */
5051         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5052         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5053         0x0000ffff                              /* end                      */
5054     };
5055     const DWORD normal_code[] = {
5056         0xffff0300,                             /* ps_3_0                   */
5057         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5058         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5059         0x0000ffff                              /* end                      */
5060     };
5061     /* psize: fails? */
5062     const DWORD texcoord0_code[] = {
5063         0xffff0300,                             /* ps_3_0                   */
5064         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5065         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5066         0x0000ffff                              /* end                      */
5067     };
5068     const DWORD tangent_code[] = {
5069         0xffff0300,                             /* ps_3_0                   */
5070         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5071         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5072         0x0000ffff                              /* end                      */
5073     };
5074     const DWORD binormal_code[] = {
5075         0xffff0300,                             /* ps_3_0                   */
5076         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5077         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5078         0x0000ffff                              /* end                      */
5079     };
5080     /* tessfactor: fails */
5081     /* positiont: fails */
5082     const DWORD color_code[] = {
5083         0xffff0300,                             /* ps_3_0                   */
5084         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5085         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5086         0x0000ffff                              /* end                      */
5087     };
5088     const DWORD fog_code[] = {
5089         0xffff0300,                             /* ps_3_0                   */
5090         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5091         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5092         0x0000ffff                              /* end                      */
5093     };
5094     const DWORD depth_code[] = {
5095         0xffff0300,                             /* ps_3_0                   */
5096         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5097         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5098         0x0000ffff                              /* end                      */
5099     };
5100     const DWORD specular_code[] = {
5101         0xffff0300,                             /* ps_3_0                   */
5102         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5103         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5104         0x0000ffff                              /* end                      */
5105     };
5106     /* sample: fails */
5107
5108     struct varying_test_struct tests[] = {
5109        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5110        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5111        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5112        /* Why does dx not forward the texcoord? */
5113        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5114        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5115        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5116        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5117        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5118        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5119        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5120     };
5121     /* Declare a monster vertex type :-) */
5122     static const D3DVERTEXELEMENT9 decl_elements[] = {
5123         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5124         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5125         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5126         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5127         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5128         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5129         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5130         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5131         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5132         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5133         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5134         D3DDECL_END()
5135     };
5136     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5137         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5138         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5139         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5140         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5141         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5142         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5143         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5144         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5145         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5146         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5147         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5148         D3DDECL_END()
5149     };
5150     struct hugeVertex data[4] = {
5151         {
5152             -1.0,   -1.0,   0.1,    1.0,
5153              0.1,    0.1,   0.1,    0.1,
5154              0.2,    0.2,   0.2,    0.2,
5155              0.3,    0.3,   0.3,    0.3,
5156              0.4,    0.4,   0.4,    0.4,
5157              0.50,   0.55,  0.55,   0.55,
5158              0.6,    0.6,   0.6,    0.7,
5159              0.7,    0.7,   0.7,    0.6,
5160              0.8,    0.8,   0.8,    0.8,
5161              0xe6e6e6e6, /* 0.9 * 256 */
5162              0x224488ff  /* Nothing special */
5163         },
5164         {
5165              1.0,   -1.0,   0.1,    1.0,
5166              0.1,    0.1,   0.1,    0.1,
5167              0.2,    0.2,   0.2,    0.2,
5168              0.3,    0.3,   0.3,    0.3,
5169              0.4,    0.4,   0.4,    0.4,
5170              0.50,   0.55,  0.55,   0.55,
5171              0.6,    0.6,   0.6,    0.7,
5172              0.7,    0.7,   0.7,    0.6,
5173              0.8,    0.8,   0.8,    0.8,
5174              0xe6e6e6e6, /* 0.9 * 256 */
5175              0x224488ff /* Nothing special */
5176         },
5177         {
5178             -1.0,    1.0,   0.1,    1.0,
5179              0.1,    0.1,   0.1,    0.1,
5180              0.2,    0.2,   0.2,    0.2,
5181              0.3,    0.3,   0.3,    0.3,
5182              0.4,    0.4,   0.4,    0.4,
5183              0.50,   0.55,  0.55,   0.55,
5184              0.6,    0.6,   0.6,    0.7,
5185              0.7,    0.7,   0.7,    0.6,
5186              0.8,    0.8,   0.8,    0.8,
5187              0xe6e6e6e6, /* 0.9 * 256 */
5188              0x224488ff /* Nothing special */
5189         },
5190         {
5191              1.0,    1.0,   0.1,    1.0,
5192              0.1,    0.1,   0.1,    0.1,
5193              0.2,    0.2,   0.2,    0.2,
5194              0.3,    0.3,   0.3,    0.3,
5195              0.4,    0.4,   0.4,    0.4,
5196              0.50,   0.55,  0.55,   0.55,
5197              0.6,    0.6,   0.6,    0.7,
5198              0.7,    0.7,   0.7,    0.6,
5199              0.8,    0.8,   0.8,    0.8,
5200              0xe6e6e6e6, /* 0.9 * 256 */
5201              0x224488ff /* Nothing special */
5202         },
5203     };
5204     struct hugeVertex data2[4];
5205     IDirect3DVertexDeclaration9 *decl;
5206     IDirect3DVertexDeclaration9 *decl2;
5207     HRESULT hr;
5208     unsigned int i;
5209     DWORD color, r, g, b, r_e, g_e, b_e;
5210     BOOL drawok;
5211
5212     memcpy(data2, data, sizeof(data2));
5213     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5214     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5215     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5216     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5217
5218     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5219     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5220     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5221     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5222     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5223     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5224
5225     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5226     {
5227         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5228         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5229            tests[i].name, hr);
5230     }
5231
5232     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5233     {
5234         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5235         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5236
5237         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5238         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5239
5240         hr = IDirect3DDevice9_BeginScene(device);
5241         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5242         drawok = FALSE;
5243         if(SUCCEEDED(hr))
5244         {
5245             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5246             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5247             drawok = SUCCEEDED(hr);
5248             hr = IDirect3DDevice9_EndScene(device);
5249             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5250         }
5251         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5252         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5253
5254         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5255          * the failure and do not check the color if it failed
5256          */
5257         if(!drawok) {
5258             continue;
5259         }
5260
5261         color = getPixelColor(device, 360, 240);
5262         r = color & 0x00ff0000 >> 16;
5263         g = color & 0x0000ff00 >>  8;
5264         b = color & 0x000000ff;
5265         r_e = tests[i].color & 0x00ff0000 >> 16;
5266         g_e = tests[i].color & 0x0000ff00 >>  8;
5267         b_e = tests[i].color & 0x000000ff;
5268
5269         if(tests[i].todo) {
5270             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5271                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5272                          tests[i].name, color, tests[i].color);
5273         } else {
5274             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5275                "Test %s returned color 0x%08x, expected 0x%08x\n",
5276                tests[i].name, color, tests[i].color);
5277         }
5278     }
5279
5280     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5281     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5282     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5283     {
5284         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5285         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5286
5287         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5288         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5289
5290         hr = IDirect3DDevice9_BeginScene(device);
5291         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5292         if(SUCCEEDED(hr))
5293         {
5294             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5295             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5296             hr = IDirect3DDevice9_EndScene(device);
5297             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5298         }
5299         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5300         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5301
5302         color = getPixelColor(device, 360, 240);
5303         r = color & 0x00ff0000 >> 16;
5304         g = color & 0x0000ff00 >>  8;
5305         b = color & 0x000000ff;
5306         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5307         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5308         b_e = tests[i].color_rhw & 0x000000ff;
5309
5310         if(tests[i].todo_rhw) {
5311             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5312              * pipeline
5313              */
5314             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5315                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5316                          tests[i].name, color, tests[i].color_rhw);
5317         } else {
5318             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5319                "Test %s returned color 0x%08x, expected 0x%08x\n",
5320                tests[i].name, color, tests[i].color_rhw);
5321         }
5322     }
5323
5324     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5325     {
5326         IDirect3DPixelShader9_Release(tests[i].shader);
5327     }
5328
5329     IDirect3DVertexDeclaration9_Release(decl2);
5330     IDirect3DVertexDeclaration9_Release(decl);
5331 }
5332
5333 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5334     static const DWORD ps_code[] = {
5335     0xffff0300,                                                             /* ps_3_0                       */
5336     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5337     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5338     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5339     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5340     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5341     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5342     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5343     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5344     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5345
5346     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5347     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5348     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5349     0x0000001d,                                                             /* endloop                      */
5350     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5351     0x0000ffff                                                              /* end                          */
5352     };
5353     static const DWORD vs_1_code[] = {
5354     0xfffe0101,                                                             /* vs_1_1                       */
5355     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5356     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5357     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5358     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5359     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5360     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5361     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5362     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5363     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5364     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5365     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5366     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5367     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5368     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5369     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5370     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5371     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5372     0x0000ffff
5373     };
5374     DWORD vs_2_code[] = {
5375     0xfffe0200,                                                             /* vs_2_0                       */
5376     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5377     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5378     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5379     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5380     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5381     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5382     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5383     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5384     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5385     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5386     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5387     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5388     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5389     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5390     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5391     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5392     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5393     0x0000ffff                                                              /* end                          */
5394     };
5395     /* TODO: Define normal, tangent, blendweight and depth here */
5396     static const DWORD vs_3_code[] = {
5397     0xfffe0300,                                                             /* vs_3_0                       */
5398     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5399     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5400     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5401     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5402     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5403     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5404     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5405     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5406     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5407     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5408     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5409     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5410     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5411     0x0000ffff                                                              /* end                          */
5412     };
5413     float quad1[] =  {
5414         -1.0,   -1.0,   0.1,
5415          0.0,   -1.0,   0.1,
5416         -1.0,    0.0,   0.1,
5417          0.0,    0.0,   0.1
5418     };
5419     float quad2[] =  {
5420          0.0,   -1.0,   0.1,
5421          1.0,   -1.0,   0.1,
5422          0.0,    0.0,   0.1,
5423          1.0,    0.0,   0.1
5424     };
5425     float quad3[] =  {
5426         -1.0,    0.0,   0.1,
5427          0.0,    0.0,   0.1,
5428         -1.0,    1.0,   0.1,
5429          0.0,    1.0,   0.1
5430     };
5431
5432     HRESULT hr;
5433     DWORD color;
5434     IDirect3DPixelShader9 *pixelshader = NULL;
5435     IDirect3DVertexShader9 *vs_1_shader = NULL;
5436     IDirect3DVertexShader9 *vs_2_shader = NULL;
5437     IDirect3DVertexShader9 *vs_3_shader = NULL;
5438
5439     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5440
5441     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5442     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5443     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5444     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5445     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5446     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5447     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5448     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5449     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5450     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5451     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5452
5453     hr = IDirect3DDevice9_BeginScene(device);
5454     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5455     if(SUCCEEDED(hr))
5456     {
5457         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5458         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5459         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5460         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5461
5462         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5463         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5464         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5465         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5466
5467         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5468         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5469         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5470         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5471
5472         hr = IDirect3DDevice9_EndScene(device);
5473         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5474     }
5475     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5476     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5477
5478     color = getPixelColor(device, 160, 120);
5479     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5480        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5481     color = getPixelColor(device, 160, 360);
5482     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5483        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5484     color = getPixelColor(device, 480, 360);
5485     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5486        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5487
5488     /* cleanup */
5489     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5490     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5491     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5492     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5493     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5494     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5495     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5496     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5497 }
5498
5499 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5500     static const DWORD vs_code[] = {
5501     0xfffe0300,                                                             /* vs_3_0                       */
5502     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5503     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5504     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5505     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5506     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5507     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5508     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5509     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5510     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5511     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5512     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5513     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5514     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5515
5516     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5517     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5518     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5519     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5520     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5521     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5522     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5523     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5524     0x0000ffff                                                              /* end                          */
5525     };
5526     static const DWORD ps_1_code[] = {
5527     0xffff0104,                                                             /* ps_1_4                       */
5528     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5529     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5530     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5531     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5532     0x0000ffff                                                              /* end                          */
5533     };
5534     static const DWORD ps_2_code[] = {
5535     0xffff0200,                                                             /* ps_2_0                       */
5536     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5537     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5538     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5539
5540     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5541     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5542     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5543     0x0000ffff                                                              /* end                          */
5544     };
5545     static const DWORD ps_3_code[] = {
5546     0xffff0300,                                                             /* ps_3_0                       */
5547     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5548     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5549     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5550
5551     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5552     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5553     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5554     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5555     0x0000ffff                                                              /* end                          */
5556     };
5557
5558     float quad1[] =  {
5559         -1.0,   -1.0,   0.1,
5560          0.0,   -1.0,   0.1,
5561         -1.0,    0.0,   0.1,
5562          0.0,    0.0,   0.1
5563     };
5564     float quad2[] =  {
5565          0.0,   -1.0,   0.1,
5566          1.0,   -1.0,   0.1,
5567          0.0,    0.0,   0.1,
5568          1.0,    0.0,   0.1
5569     };
5570     float quad3[] =  {
5571         -1.0,    0.0,   0.1,
5572          0.0,    0.0,   0.1,
5573         -1.0,    1.0,   0.1,
5574          0.0,    1.0,   0.1
5575     };
5576     float quad4[] =  {
5577          0.0,    0.0,   0.1,
5578          1.0,    0.0,   0.1,
5579          0.0,    1.0,   0.1,
5580          1.0,    1.0,   0.1
5581     };
5582
5583     HRESULT hr;
5584     DWORD color;
5585     IDirect3DVertexShader9 *vertexshader = NULL;
5586     IDirect3DPixelShader9 *ps_1_shader = NULL;
5587     IDirect3DPixelShader9 *ps_2_shader = NULL;
5588     IDirect3DPixelShader9 *ps_3_shader = NULL;
5589     IDirect3DTexture9 *texture = NULL;
5590     D3DLOCKED_RECT lr;
5591     unsigned int x, y;
5592
5593     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5594
5595     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5596     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5597     if(FAILED(hr)) {
5598         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5599         return;
5600     }
5601     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5602     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5603     for(y = 0; y < 512; y++) {
5604         for(x = 0; x < 512; x++) {
5605             double r_f = (double) x / (double) 512;
5606             double g_f = (double) y / (double) 512;
5607             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5608             unsigned short r = (unsigned short) (r_f * 65535.0);
5609             unsigned short g = (unsigned short) (g_f * 65535.0);
5610             dst[0] = r;
5611             dst[1] = g;
5612             dst[2] = 0;
5613             dst[3] = 65535;
5614         }
5615     }
5616     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5617     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5618
5619     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5620     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5621     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5622     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5623     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5624     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5625     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5626     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5627     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5628     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5629     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5630
5631     hr = IDirect3DDevice9_BeginScene(device);
5632     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5633     if(SUCCEEDED(hr))
5634     {
5635         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5636         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5638         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5639
5640         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5641         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5642         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5643         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5644
5645         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5646         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5647         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5648         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5649
5650         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5651         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5652         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5653         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5654         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5655         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5656         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5657         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5658         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5659         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5660
5661         hr = IDirect3DDevice9_EndScene(device);
5662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5663     }
5664     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5665     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5666
5667     color = getPixelColor(device, 160, 120);
5668     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5669        (color & 0x0000ff00) == 0x0000ff00 &&
5670        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5671        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5672     color = getPixelColor(device, 160, 360);
5673     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5674        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5675        (color & 0x000000ff) == 0x00000000,
5676        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5677     color = getPixelColor(device, 480, 360);
5678     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5679        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5680        (color & 0x000000ff) == 0x00000000,
5681        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5682     color = getPixelColor(device, 480, 160);
5683     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5684        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5685        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5686        (color & 0x000000ff) == 0x00000000),
5687        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5688
5689     /* cleanup */
5690     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5691     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5692     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5693     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5694     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5695     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5696     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5697     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5698     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5699     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5700     if(texture) IDirect3DTexture9_Release(texture);
5701 }
5702
5703 void test_compare_instructions(IDirect3DDevice9 *device)
5704 {
5705     DWORD shader_sge_vec_code[] = {
5706         0xfffe0101,                                         /* vs_1_1                   */
5707         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5708         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5709         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5710         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5711         0x0000ffff                                          /* end                      */
5712     };
5713     DWORD shader_slt_vec_code[] = {
5714         0xfffe0101,                                         /* vs_1_1                   */
5715         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5716         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5717         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5718         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5719         0x0000ffff                                          /* end                      */
5720     };
5721     DWORD shader_sge_scalar_code[] = {
5722         0xfffe0101,                                         /* vs_1_1                   */
5723         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5724         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5725         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5726         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5727         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5728         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5729         0x0000ffff                                          /* end                      */
5730     };
5731     DWORD shader_slt_scalar_code[] = {
5732         0xfffe0101,                                         /* vs_1_1                   */
5733         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5734         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5735         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5736         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5737         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5738         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5739         0x0000ffff                                          /* end                      */
5740     };
5741     IDirect3DVertexShader9 *shader_sge_vec;
5742     IDirect3DVertexShader9 *shader_slt_vec;
5743     IDirect3DVertexShader9 *shader_sge_scalar;
5744     IDirect3DVertexShader9 *shader_slt_scalar;
5745     HRESULT hr, color;
5746     float quad1[] =  {
5747         -1.0,   -1.0,   0.1,
5748          0.0,   -1.0,   0.1,
5749         -1.0,    0.0,   0.1,
5750          0.0,    0.0,   0.1
5751     };
5752     float quad2[] =  {
5753          0.0,   -1.0,   0.1,
5754          1.0,   -1.0,   0.1,
5755          0.0,    0.0,   0.1,
5756          1.0,    0.0,   0.1
5757     };
5758     float quad3[] =  {
5759         -1.0,    0.0,   0.1,
5760          0.0,    0.0,   0.1,
5761         -1.0,    1.0,   0.1,
5762          0.0,    1.0,   0.1
5763     };
5764     float quad4[] =  {
5765          0.0,    0.0,   0.1,
5766          1.0,    0.0,   0.1,
5767          0.0,    1.0,   0.1,
5768          1.0,    1.0,   0.1
5769     };
5770     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5771     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5772
5773     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5774
5775     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5776     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5777     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5778     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5779     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5780     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5781     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5782     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5783     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5784     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5785     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5786     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5787     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5788     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5789
5790     hr = IDirect3DDevice9_BeginScene(device);
5791     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5792     if(SUCCEEDED(hr))
5793     {
5794         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5795         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5797         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5798
5799         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5800         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5803
5804         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5805         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5806         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5807         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5808
5809         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5810         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5811
5812         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5813         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5814         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5815         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5816
5817         hr = IDirect3DDevice9_EndScene(device);
5818         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5819     }
5820
5821     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5822     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5823     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5824     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5825
5826     color = getPixelColor(device, 160, 360);
5827     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5828     color = getPixelColor(device, 480, 360);
5829     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5830     color = getPixelColor(device, 160, 120);
5831     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5832     color = getPixelColor(device, 480, 160);
5833     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5834
5835     IDirect3DVertexShader9_Release(shader_sge_vec);
5836     IDirect3DVertexShader9_Release(shader_slt_vec);
5837     IDirect3DVertexShader9_Release(shader_sge_scalar);
5838     IDirect3DVertexShader9_Release(shader_slt_scalar);
5839 }
5840
5841 void test_vshader_input(IDirect3DDevice9 *device)
5842 {
5843     DWORD swapped_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, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5849         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5850         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5851         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5852         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5853         0x0000ffff                                          /* end                  */
5854     };
5855     DWORD swapped_shader_code_1[] = {
5856         0xfffe0101,                                         /* vs_1_1               */
5857         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5858         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5859         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5860         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5861         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5862         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5863         0x0000ffff                                          /* end                  */
5864     };
5865     DWORD swapped_shader_code_2[] = {
5866         0xfffe0200,                                         /* vs_2_0               */
5867         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5868         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5869         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5870         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5871         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5872         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5873         0x0000ffff                                          /* end                  */
5874     };
5875     DWORD texcoord_color_shader_code_3[] = {
5876         0xfffe0300,                                         /* vs_3_0               */
5877         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5878         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5879         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5880         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5881         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5882         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5883         0x0000ffff                                          /* end                  */
5884     };
5885     DWORD texcoord_color_shader_code_2[] = {
5886         0xfffe0200,                                         /* vs_2_0               */
5887         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5888         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5889         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5890         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5891         0x0000ffff                                          /* end                  */
5892     };
5893     DWORD texcoord_color_shader_code_1[] = {
5894         0xfffe0101,                                         /* vs_1_1               */
5895         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5896         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5897         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5898         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5899         0x0000ffff                                          /* end                  */
5900     };
5901     DWORD color_color_shader_code_3[] = {
5902         0xfffe0300,                                         /* vs_3_0               */
5903         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5904         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5905         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5906         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5907         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5908         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5909         0x0000ffff                                          /* end                  */
5910     };
5911     DWORD color_color_shader_code_2[] = {
5912         0xfffe0200,                                         /* vs_2_0               */
5913         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5914         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5915         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5916         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5917         0x0000ffff                                          /* end                  */
5918     };
5919     DWORD color_color_shader_code_1[] = {
5920         0xfffe0101,                                         /* vs_1_1               */
5921         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5922         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5923         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5924         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5925         0x0000ffff                                          /* end                  */
5926     };
5927     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5928     HRESULT hr;
5929     DWORD color;
5930     float quad1[] =  {
5931         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5932          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5933         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5934          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5935     };
5936     float quad2[] =  {
5937          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5938          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5939          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5940          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5941     };
5942     float quad3[] =  {
5943         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5944          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5945         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5946          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5947     };
5948     float quad4[] =  {
5949          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5950          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5951          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5952          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5953     };
5954     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5955         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5956         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5957         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5958         D3DDECL_END()
5959     };
5960     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5961         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5962         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5963         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5964         D3DDECL_END()
5965     };
5966     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5967         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5968         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5969         D3DDECL_END()
5970     };
5971     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5972         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5973         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5974         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5975         D3DDECL_END()
5976     };
5977     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5978         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5979         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5980         D3DDECL_END()
5981     };
5982     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5983         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5984         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5985         D3DDECL_END()
5986     };
5987     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5988         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5989         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5990         D3DDECL_END()
5991     };
5992     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5993         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5994         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5995         D3DDECL_END()
5996     };
5997     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5998     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5999     unsigned int i;
6000     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6001     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6002
6003     struct vertex quad1_color[] =  {
6004        {-1.0,   -1.0,   0.1,    0x00ff8040},
6005        { 0.0,   -1.0,   0.1,    0x00ff8040},
6006        {-1.0,    0.0,   0.1,    0x00ff8040},
6007        { 0.0,    0.0,   0.1,    0x00ff8040}
6008     };
6009     struct vertex quad2_color[] =  {
6010        { 0.0,   -1.0,   0.1,    0x00ff8040},
6011        { 1.0,   -1.0,   0.1,    0x00ff8040},
6012        { 0.0,    0.0,   0.1,    0x00ff8040},
6013        { 1.0,    0.0,   0.1,    0x00ff8040}
6014     };
6015     struct vertex quad3_color[] =  {
6016        {-1.0,    0.0,   0.1,    0x00ff8040},
6017        { 0.0,    0.0,   0.1,    0x00ff8040},
6018        {-1.0,    1.0,   0.1,    0x00ff8040},
6019        { 0.0,    1.0,   0.1,    0x00ff8040}
6020     };
6021     float quad4_color[] =  {
6022          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6023          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6024          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6025          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6026     };
6027
6028     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6029     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6030     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6031     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6032     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6033     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6034     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6035     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6036
6037     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6038     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6039     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6040     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6041     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6042     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6043     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6044     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6045
6046     for(i = 1; i <= 3; i++) {
6047         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6048         if(i == 3) {
6049             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6050             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6051         } else if(i == 2){
6052             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6053             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6054         } else if(i == 1) {
6055             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6056             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6057         }
6058
6059         hr = IDirect3DDevice9_BeginScene(device);
6060         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6061         if(SUCCEEDED(hr))
6062         {
6063             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6064             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6065
6066             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6067             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6068             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6069             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6070
6071             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6072             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6073             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6074             if(i == 3 || i == 2) {
6075                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6076             } else if(i == 1) {
6077                 /* Succeeds or fails, depending on SW or HW vertex processing */
6078                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6079             }
6080
6081             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6082             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6083             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6084             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6085
6086             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6087             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6088             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6089             if(i == 3 || i == 2) {
6090                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6091             } else if(i == 1) {
6092                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6093             }
6094
6095             hr = IDirect3DDevice9_EndScene(device);
6096             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6097         }
6098
6099         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6100         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6101
6102         if(i == 3 || i == 2) {
6103             color = getPixelColor(device, 160, 360);
6104             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6105                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6106
6107             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6108             color = getPixelColor(device, 480, 360);
6109             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6110                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6111             color = getPixelColor(device, 160, 120);
6112             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6113             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6114                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6115
6116             color = getPixelColor(device, 480, 160);
6117             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6118         } else if(i == 1) {
6119             color = getPixelColor(device, 160, 360);
6120             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6121                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6122             color = getPixelColor(device, 480, 360);
6123             /* Accept the clear color as well in this case, since SW VP returns an error */
6124             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6125             color = getPixelColor(device, 160, 120);
6126             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6127                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6128             color = getPixelColor(device, 480, 160);
6129             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6130         }
6131
6132         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6133         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6134
6135         /* Now find out if the whole streams are re-read, or just the last active value for the
6136          * vertices is used.
6137          */
6138         hr = IDirect3DDevice9_BeginScene(device);
6139         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6140         if(SUCCEEDED(hr))
6141         {
6142             float quad1_modified[] =  {
6143                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6144                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6145                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6146                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6147             };
6148             float quad2_modified[] =  {
6149                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6150                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6151                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6152                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6153             };
6154
6155             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6156             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6157
6158             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6159             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6160             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6161             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6162
6163             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6164             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6165             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6166             if(i == 3 || i == 2) {
6167                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6168             } else if(i == 1) {
6169                 /* Succeeds or fails, depending on SW or HW vertex processing */
6170                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6171             }
6172
6173             hr = IDirect3DDevice9_EndScene(device);
6174             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6175         }
6176         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6177         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6178
6179         color = getPixelColor(device, 480, 350);
6180         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6181          * as well.
6182          *
6183          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6184          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6185          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6186          * refrast's result.
6187          *
6188          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6189          */
6190         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6191            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6192         color = getPixelColor(device, 160, 120);
6193
6194         IDirect3DDevice9_SetVertexShader(device, NULL);
6195         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6196
6197         IDirect3DVertexShader9_Release(swapped_shader);
6198     }
6199
6200     for(i = 1; i <= 3; i++) {
6201         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6202         if(i == 3) {
6203             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6204             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6205             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6206             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6207         } else if(i == 2){
6208             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6209             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6210             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6212         } else if(i == 1) {
6213             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6214             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6215             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6216             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6217         }
6218
6219         hr = IDirect3DDevice9_BeginScene(device);
6220         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6221         if(SUCCEEDED(hr))
6222         {
6223             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6224             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6225             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6226             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6227             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6228             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6229
6230             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6231             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6232
6233             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6234             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6235             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6236             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6237             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6238             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6239
6240             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6241             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6242             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6243             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6244             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6245             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6246
6247             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6248             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6249             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6250             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6251
6252             hr = IDirect3DDevice9_EndScene(device);
6253             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6254         }
6255         IDirect3DDevice9_SetVertexShader(device, NULL);
6256         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6257
6258         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6259         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6260
6261         color = getPixelColor(device, 160, 360);
6262         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6263            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6264         color = getPixelColor(device, 480, 360);
6265         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6266            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6267         color = getPixelColor(device, 160, 120);
6268         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6269            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6270         color = getPixelColor(device, 480, 160);
6271         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6272            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6273
6274         IDirect3DVertexShader9_Release(texcoord_color_shader);
6275         IDirect3DVertexShader9_Release(color_color_shader);
6276     }
6277
6278     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6279     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6280     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6281     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6282
6283     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6284     IDirect3DVertexDeclaration9_Release(decl_color_color);
6285     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6286     IDirect3DVertexDeclaration9_Release(decl_color_float);
6287 }
6288
6289 static void srgbtexture_test(IDirect3DDevice9 *device)
6290 {
6291     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6292      * texture stage state to render a quad using that texture.  The resulting
6293      * color components should be 0x36 (~ 0.21), per this formula:
6294      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6295      * This is true where srgb_color > 0.04045.
6296      */
6297     IDirect3D9 *d3d = NULL;
6298     HRESULT hr;
6299     LPDIRECT3DTEXTURE9 texture = NULL;
6300     LPDIRECT3DSURFACE9 surface = NULL;
6301     D3DLOCKED_RECT lr;
6302     DWORD color;
6303     float quad[] = {
6304         -1.0,       1.0,       0.0,     0.0,    0.0,
6305          1.0,       1.0,       0.0,     1.0,    0.0,
6306         -1.0,      -1.0,       0.0,     0.0,    1.0,
6307          1.0,      -1.0,       0.0,     1.0,    1.0,
6308     };
6309
6310
6311     memset(&lr, 0, sizeof(lr));
6312     IDirect3DDevice9_GetDirect3D(device, &d3d);
6313     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6314                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6315                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6316         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6317         goto out;
6318     }
6319
6320     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6321                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6322                                         &texture, NULL);
6323     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6324     if(!texture) {
6325         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6326         goto out;
6327     }
6328     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6329     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6330
6331     fill_surface(surface, 0xff7f7f7f);
6332     IDirect3DSurface9_Release(surface);
6333
6334     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6335     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6336     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6337     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6338
6339     hr = IDirect3DDevice9_BeginScene(device);
6340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6341     if(SUCCEEDED(hr))
6342     {
6343         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6344         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6345
6346         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6347         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6348
6349
6350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6351         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6352
6353         hr = IDirect3DDevice9_EndScene(device);
6354         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6355     }
6356
6357     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6358     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6359     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6360     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6361
6362     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6363     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6364
6365     color = getPixelColor(device, 320, 240);
6366     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6367
6368 out:
6369     if(texture) IDirect3DTexture9_Release(texture);
6370     IDirect3D9_Release(d3d);
6371 }
6372
6373 static void shademode_test(IDirect3DDevice9 *device)
6374 {
6375     /* Render a quad and try all of the different fixed function shading models. */
6376     HRESULT hr;
6377     DWORD color0, color1;
6378     DWORD color0_gouraud = 0, color1_gouraud = 0;
6379     DWORD shademode = D3DSHADE_FLAT;
6380     DWORD primtype = D3DPT_TRIANGLESTRIP;
6381     LPVOID data = NULL;
6382     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6383     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6384     UINT i, j;
6385     struct vertex quad_strip[] =
6386     {
6387         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6388         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6389         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6390         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6391     };
6392     struct vertex quad_list[] =
6393     {
6394         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6395         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6396         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6397
6398         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6399         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6400         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6401     };
6402
6403     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6404                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6405     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6406     if (FAILED(hr)) goto bail;
6407
6408     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6409                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6410     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6411     if (FAILED(hr)) goto bail;
6412
6413     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6414     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6415
6416     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6417     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6418
6419     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6420     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6421     memcpy(data, quad_strip, sizeof(quad_strip));
6422     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6423     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6424
6425     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6426     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6427     memcpy(data, quad_list, sizeof(quad_list));
6428     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6429     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6430
6431     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6432      * the color fixups we have to do for FLAT shading will be dependent on that. */
6433     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6434     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6435
6436     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6437     for (j=0; j<2; j++) {
6438
6439         /* Inner loop just changes the D3DRS_SHADEMODE */
6440         for (i=0; i<3; i++) {
6441             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6442             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6443
6444             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6445             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6446
6447             hr = IDirect3DDevice9_BeginScene(device);
6448             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6449             if(SUCCEEDED(hr))
6450             {
6451                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6452                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6453
6454                 hr = IDirect3DDevice9_EndScene(device);
6455                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6456             }
6457
6458             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6459             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6460
6461             /* Sample two spots from the output */
6462             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6463             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6464             switch(shademode) {
6465                 case D3DSHADE_FLAT:
6466                     /* Should take the color of the first vertex of each triangle */
6467                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6468                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6469                     shademode = D3DSHADE_GOURAUD;
6470                     break;
6471                 case D3DSHADE_GOURAUD:
6472                     /* Should be an interpolated blend */
6473
6474                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6475                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6476                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6477                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6478
6479                     color0_gouraud = color0;
6480                     color1_gouraud = color1;
6481
6482                     shademode = D3DSHADE_PHONG;
6483                     break;
6484                 case D3DSHADE_PHONG:
6485                     /* Should be the same as GOURAUD, since no hardware implements this */
6486                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6487                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6488                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6489                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6490
6491                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6492                             color0_gouraud, color0);
6493                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6494                             color1_gouraud, color1);
6495                     break;
6496             }
6497         }
6498         /* Now, do it all over again with a TRIANGLELIST */
6499         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6500         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6501         primtype = D3DPT_TRIANGLELIST;
6502         shademode = D3DSHADE_FLAT;
6503     }
6504
6505 bail:
6506     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6507     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6508     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6509     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6510
6511     if (vb_strip)
6512         IDirect3DVertexBuffer9_Release(vb_strip);
6513     if (vb_list)
6514         IDirect3DVertexBuffer9_Release(vb_list);
6515 }
6516
6517
6518 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6519 {
6520     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6521      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6522      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6523      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6524      * 0.73
6525      *
6526      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6527      * so use shaders for this task
6528      */
6529     IDirect3DPixelShader9 *pshader;
6530     IDirect3DVertexShader9 *vshader;
6531     IDirect3D9 *d3d;
6532     DWORD vshader_code[] = {
6533         0xfffe0101,                                                             /* vs_1_1                       */
6534         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6535         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6536         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6537         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6538         0x0000ffff                                                              /* end                          */
6539     };
6540     DWORD pshader_code[] = {
6541         0xffff0101,                                                             /* ps_1_1                       */
6542         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6543         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6544         0x0000ffff                                                              /* end                          */
6545     };
6546     const float quad[] = {
6547        -1.0,   -1.0,    0.1,
6548         1.0,   -1.0,    0.1,
6549        -1.0,    1.0,    0.1,
6550         1.0,    1.0,    0.1
6551     };
6552     HRESULT hr;
6553     DWORD color;
6554
6555     IDirect3DDevice9_GetDirect3D(device, &d3d);
6556     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6557      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6558      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6559      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6560      * works
6561      */
6562     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6563                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6564                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6565         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6566         IDirect3D9_Release(d3d);
6567         return;
6568     }
6569     IDirect3D9_Release(d3d);
6570
6571     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6572     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6573
6574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6577     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6578     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6579     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6580     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6581     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6582     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6583     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6584
6585     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6586     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6587     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6588     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6589     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6590     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6591     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6592     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6593     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6594     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6595
6596     hr = IDirect3DDevice9_BeginScene(device);
6597     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6598     if(SUCCEEDED(hr)) {
6599         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6600         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6601
6602         hr = IDirect3DDevice9_EndScene(device);
6603         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6604     }
6605
6606     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6607     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6608     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6609     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6610     IDirect3DPixelShader9_Release(pshader);
6611     IDirect3DVertexShader9_Release(vshader);
6612
6613     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6614     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6615     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6616     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6617
6618     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6619     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6620     color = getPixelColor(device, 160, 360);
6621     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6622        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6623 }
6624
6625 static void alpha_test(IDirect3DDevice9 *device)
6626 {
6627     HRESULT hr;
6628     IDirect3DTexture9 *offscreenTexture;
6629     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6630     DWORD color;
6631
6632     struct vertex quad1[] =
6633     {
6634         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6635         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6636         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6637         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6638     };
6639     struct vertex quad2[] =
6640     {
6641         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6642         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6643         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6644         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6645     };
6646     static const float composite_quad[][5] = {
6647         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6648         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6649         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6650         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6651     };
6652
6653     /* Clear the render target with alpha = 0.5 */
6654     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6655     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6656
6657     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6658     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6659
6660     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6661     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6662     if(!backbuffer) {
6663         goto out;
6664     }
6665
6666     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6667     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6668     if(!offscreen) {
6669         goto out;
6670     }
6671
6672     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6673     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6674
6675     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6676     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6677     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6678     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6679     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6680     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6681     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6682     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6683     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6684     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6685
6686     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6687     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6688     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6689
6690         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6691         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6692         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6693         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6694         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6695         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6696         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6697
6698         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6699         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6700         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6701         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6702         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6703         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6704
6705         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6706          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6707          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6708         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6709         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6710         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6711         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6712
6713         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6714         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6715         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6716         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6717         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6718         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6719
6720         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6721         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6722         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6723         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6724         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6725         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6726
6727         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6728         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6729
6730         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6731          * Disable alpha blending for the final composition
6732          */
6733         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6734         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6735         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6736         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6737
6738         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6739         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6740         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6741         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6742         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6743         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6744
6745         hr = IDirect3DDevice9_EndScene(device);
6746         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6747     }
6748
6749     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6750
6751     color = getPixelColor(device, 160, 360);
6752     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6753        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6754
6755     color = getPixelColor(device, 160, 120);
6756     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6757        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6758
6759     color = getPixelColor(device, 480, 360);
6760     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6761        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6762
6763     color = getPixelColor(device, 480, 120);
6764     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6765        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6766
6767     out:
6768     /* restore things */
6769     if(backbuffer) {
6770         IDirect3DSurface9_Release(backbuffer);
6771     }
6772     if(offscreenTexture) {
6773         IDirect3DTexture9_Release(offscreenTexture);
6774     }
6775     if(offscreen) {
6776         IDirect3DSurface9_Release(offscreen);
6777     }
6778 }
6779
6780 struct vertex_shortcolor {
6781     float x, y, z;
6782     unsigned short r, g, b, a;
6783 };
6784 struct vertex_floatcolor {
6785     float x, y, z;
6786     float r, g, b, a;
6787 };
6788
6789 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6790 {
6791     HRESULT hr;
6792     BOOL s_ok, ub_ok, f_ok;
6793     DWORD color, size, i;
6794     void *data;
6795     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6796         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6797         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6798         D3DDECL_END()
6799     };
6800     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6801         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6802         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6803         D3DDECL_END()
6804     };
6805     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6806         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6807         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6808         D3DDECL_END()
6809     };
6810     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6811         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6812         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6813         D3DDECL_END()
6814     };
6815     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6816         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6817         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6818         D3DDECL_END()
6819     };
6820     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6821         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6822         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6823         D3DDECL_END()
6824     };
6825     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6826         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6827         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6828         D3DDECL_END()
6829     };
6830     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6831     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6832     IDirect3DVertexBuffer9 *vb, *vb2;
6833     struct vertex quad1[] =                             /* D3DCOLOR */
6834     {
6835         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6836         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6837         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6838         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6839     };
6840     struct vertex quad2[] =                             /* UBYTE4N */
6841     {
6842         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6843         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6844         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6845         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6846     };
6847     struct vertex_shortcolor quad3[] =                  /* short */
6848     {
6849         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6850         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6851         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6852         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6853     };
6854     struct vertex_floatcolor quad4[] =
6855     {
6856         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6857         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6858         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6859         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6860     };
6861     DWORD colors[] = {
6862         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6863         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6864         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6865         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6866         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6867         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6868         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6869         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6870         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6871         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6872         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6873         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6874         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6875         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6876         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6877         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6878     };
6879     float quads[] = {
6880         -1.0,   -1.0,     0.1,
6881         -1.0,    0.0,     0.1,
6882          0.0,   -1.0,     0.1,
6883          0.0,    0.0,     0.1,
6884
6885          0.0,   -1.0,     0.1,
6886          0.0,    0.0,     0.1,
6887          1.0,   -1.0,     0.1,
6888          1.0,    0.0,     0.1,
6889
6890          0.0,    0.0,     0.1,
6891          0.0,    1.0,     0.1,
6892          1.0,    0.0,     0.1,
6893          1.0,    1.0,     0.1,
6894
6895         -1.0,    0.0,     0.1,
6896         -1.0,    1.0,     0.1,
6897          0.0,    0.0,     0.1,
6898          0.0,    1.0,     0.1
6899     };
6900     struct tvertex quad_transformed[] = {
6901        {  90,    110,     0.1,      2.0,        0x00ffff00},
6902        { 570,    110,     0.1,      2.0,        0x00ffff00},
6903        {  90,    300,     0.1,      2.0,        0x00ffff00},
6904        { 570,    300,     0.1,      2.0,        0x00ffff00}
6905     };
6906     D3DCAPS9 caps;
6907
6908     memset(&caps, 0, sizeof(caps));
6909     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6910     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6911
6912     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6913     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6914
6915     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6916     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6917     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6918     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6919     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6920     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6921     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6922         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6923         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6924         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6925         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6926     } else {
6927         trace("D3DDTCAPS_UBYTE4N not supported\n");
6928         dcl_ubyte_2 = NULL;
6929         dcl_ubyte = NULL;
6930     }
6931     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6932     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6933     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6934     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6935
6936     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6937     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6938                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6939     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6940
6941     hr = IDirect3DDevice9_BeginScene(device);
6942     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6943     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6944     if(SUCCEEDED(hr)) {
6945         if(dcl_color) {
6946             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6947             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6948             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6949             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6950         }
6951
6952         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6953          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6954          * using software vertex processing. Doh!
6955          */
6956         if(dcl_ubyte) {
6957             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6958             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6959             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6960             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6961             ub_ok = SUCCEEDED(hr);
6962         }
6963
6964         if(dcl_short) {
6965             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6966             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6967             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6968             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6969             s_ok = SUCCEEDED(hr);
6970         }
6971
6972         if(dcl_float) {
6973             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6974             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6975             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6976             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6977             f_ok = SUCCEEDED(hr);
6978         }
6979
6980         hr = IDirect3DDevice9_EndScene(device);
6981         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6982     }
6983
6984     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6985     if(dcl_short) {
6986         color = getPixelColor(device, 480, 360);
6987         ok(color == 0x000000ff || !s_ok,
6988            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6989     }
6990     if(dcl_ubyte) {
6991         color = getPixelColor(device, 160, 120);
6992         ok(color == 0x0000ffff || !ub_ok,
6993            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6994     }
6995     if(dcl_color) {
6996         color = getPixelColor(device, 160, 360);
6997         ok(color == 0x00ffff00,
6998            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6999     }
7000     if(dcl_float) {
7001         color = getPixelColor(device, 480, 120);
7002         ok(color == 0x00ff0000 || !f_ok,
7003            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7004     }
7005
7006     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7007      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7008      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7009      * whether the immediate mode code works
7010      */
7011     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7012     hr = IDirect3DDevice9_BeginScene(device);
7013     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7014     if(SUCCEEDED(hr)) {
7015         if(dcl_color) {
7016             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7017             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7018             memcpy(data, quad1, sizeof(quad1));
7019             hr = IDirect3DVertexBuffer9_Unlock(vb);
7020             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7021             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7022             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7023             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7024             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7025             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7026             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7027         }
7028
7029         if(dcl_ubyte) {
7030             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7031             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7032             memcpy(data, quad2, sizeof(quad2));
7033             hr = IDirect3DVertexBuffer9_Unlock(vb);
7034             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7035             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7036             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7037             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7038             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7039             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7040             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7041                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7042             ub_ok = SUCCEEDED(hr);
7043         }
7044
7045         if(dcl_short) {
7046             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7047             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7048             memcpy(data, quad3, sizeof(quad3));
7049             hr = IDirect3DVertexBuffer9_Unlock(vb);
7050             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7051             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7052             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7053             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7054             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7055             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7056             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7057                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7058             s_ok = SUCCEEDED(hr);
7059         }
7060
7061         if(dcl_float) {
7062             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7063             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7064             memcpy(data, quad4, sizeof(quad4));
7065             hr = IDirect3DVertexBuffer9_Unlock(vb);
7066             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7067             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7068             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7069             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7070             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7071             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7072             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7073                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7074             f_ok = SUCCEEDED(hr);
7075         }
7076
7077         hr = IDirect3DDevice9_EndScene(device);
7078         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7079     }
7080
7081     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7082     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7083     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7084     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7085
7086     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7087     if(dcl_short) {
7088         color = getPixelColor(device, 480, 360);
7089         ok(color == 0x000000ff || !s_ok,
7090            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7091     }
7092     if(dcl_ubyte) {
7093         color = getPixelColor(device, 160, 120);
7094         ok(color == 0x0000ffff || !ub_ok,
7095            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7096     }
7097     if(dcl_color) {
7098         color = getPixelColor(device, 160, 360);
7099         ok(color == 0x00ffff00,
7100            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7101     }
7102     if(dcl_float) {
7103         color = getPixelColor(device, 480, 120);
7104         ok(color == 0x00ff0000 || !f_ok,
7105            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7106     }
7107
7108     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7109     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7110
7111     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7112     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7113     memcpy(data, quad_transformed, sizeof(quad_transformed));
7114     hr = IDirect3DVertexBuffer9_Unlock(vb);
7115     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7116
7117     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7118     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7119
7120     hr = IDirect3DDevice9_BeginScene(device);
7121     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7122     if(SUCCEEDED(hr)) {
7123         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7124         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7125         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7126         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7127
7128         hr = IDirect3DDevice9_EndScene(device);
7129         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7130     }
7131
7132     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7133     color = getPixelColor(device, 88, 108);
7134     ok(color == 0x000000ff,
7135        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7136     color = getPixelColor(device, 92, 108);
7137     ok(color == 0x000000ff,
7138        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7139     color = getPixelColor(device, 88, 112);
7140     ok(color == 0x000000ff,
7141        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7142     color = getPixelColor(device, 92, 112);
7143     ok(color == 0x00ffff00,
7144        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7145
7146     color = getPixelColor(device, 568, 108);
7147     ok(color == 0x000000ff,
7148        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7149     color = getPixelColor(device, 572, 108);
7150     ok(color == 0x000000ff,
7151        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7152     color = getPixelColor(device, 568, 112);
7153     ok(color == 0x00ffff00,
7154        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7155     color = getPixelColor(device, 572, 112);
7156     ok(color == 0x000000ff,
7157        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7158
7159     color = getPixelColor(device, 88, 298);
7160     ok(color == 0x000000ff,
7161        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7162     color = getPixelColor(device, 92, 298);
7163     ok(color == 0x00ffff00,
7164        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7165     color = getPixelColor(device, 88, 302);
7166     ok(color == 0x000000ff,
7167        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7168     color = getPixelColor(device, 92, 302);
7169     ok(color == 0x000000ff,
7170        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7171
7172     color = getPixelColor(device, 568, 298);
7173     ok(color == 0x00ffff00,
7174        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7175     color = getPixelColor(device, 572, 298);
7176     ok(color == 0x000000ff,
7177        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7178     color = getPixelColor(device, 568, 302);
7179     ok(color == 0x000000ff,
7180        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7181     color = getPixelColor(device, 572, 302);
7182     ok(color == 0x000000ff,
7183        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7184
7185     /* This test is pointless without those two declarations: */
7186     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7187         skip("color-ubyte switching test declarations aren't supported\n");
7188         goto out;
7189     }
7190
7191     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7192     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7193     memcpy(data, quads, sizeof(quads));
7194     hr = IDirect3DVertexBuffer9_Unlock(vb);
7195     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7196     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7197                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7198     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7199     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7200     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7201     memcpy(data, colors, sizeof(colors));
7202     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7203     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7204
7205     for(i = 0; i < 2; i++) {
7206         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7207         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7208
7209         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7210         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7211         if(i == 0) {
7212             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7213         } else {
7214             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7215         }
7216         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7217
7218         hr = IDirect3DDevice9_BeginScene(device);
7219         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7220         ub_ok = FALSE;
7221         if(SUCCEEDED(hr)) {
7222             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7223             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7224             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7225             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7226                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7227             ub_ok = SUCCEEDED(hr);
7228
7229             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7230             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7231             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7232             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7233
7234             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7235             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7236             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7237             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7238                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7239             ub_ok = (SUCCEEDED(hr) && ub_ok);
7240
7241             hr = IDirect3DDevice9_EndScene(device);
7242             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7243         }
7244
7245         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7246         if(i == 0) {
7247             color = getPixelColor(device, 480, 360);
7248             ok(color == 0x00ff0000,
7249                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7250             color = getPixelColor(device, 160, 120);
7251             ok(color == 0x00ffffff,
7252                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7253             color = getPixelColor(device, 160, 360);
7254             ok(color == 0x000000ff || !ub_ok,
7255                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7256             color = getPixelColor(device, 480, 120);
7257             ok(color == 0x000000ff || !ub_ok,
7258                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7259         } else {
7260             color = getPixelColor(device, 480, 360);
7261             ok(color == 0x000000ff,
7262                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7263             color = getPixelColor(device, 160, 120);
7264             ok(color == 0x00ffffff,
7265                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7266             color = getPixelColor(device, 160, 360);
7267             ok(color == 0x00ff0000 || !ub_ok,
7268                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7269             color = getPixelColor(device, 480, 120);
7270             ok(color == 0x00ff0000 || !ub_ok,
7271                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7272         }
7273     }
7274
7275     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7276     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7277     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7278     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7279     IDirect3DVertexBuffer9_Release(vb2);
7280
7281     out:
7282     IDirect3DVertexBuffer9_Release(vb);
7283     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7284     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7285     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7286     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7287     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7288     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7289     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7290 }
7291
7292 struct vertex_float16color {
7293     float x, y, z;
7294     DWORD c1, c2;
7295 };
7296
7297 static void test_vshader_float16(IDirect3DDevice9 *device)
7298 {
7299     HRESULT hr;
7300     DWORD color;
7301     void *data;
7302     static const D3DVERTEXELEMENT9 decl_elements[] = {
7303         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7304         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7305         D3DDECL_END()
7306     };
7307     IDirect3DVertexDeclaration9 *vdecl = NULL;
7308     IDirect3DVertexBuffer9 *buffer = NULL;
7309     IDirect3DVertexShader9 *shader;
7310     DWORD shader_code[] = {
7311         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7312         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7313         0x90e40001, 0x0000ffff
7314     };
7315     struct vertex_float16color quad[] = {
7316         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7317         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7318         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7319         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7320
7321         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7322         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7323         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7324         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7325
7326         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7327         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7328         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7329         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7330
7331         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7332         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7333         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7334         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7335     };
7336
7337     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7338     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7339
7340     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7341     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7342     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7343     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7344     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7345     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7346
7347     hr = IDirect3DDevice9_BeginScene(device);
7348     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7349     if(SUCCEEDED(hr)) {
7350         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7351         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7352         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7353         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7354         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7355         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7356         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7357         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7358         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7359         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7360
7361         hr = IDirect3DDevice9_EndScene(device);
7362         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7363     }
7364     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7365     color = getPixelColor(device, 480, 360);
7366     ok(color == 0x00ff0000,
7367        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7368     color = getPixelColor(device, 160, 120);
7369     ok(color == 0x00000000,
7370        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7371     color = getPixelColor(device, 160, 360);
7372     ok(color == 0x0000ff00,
7373        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7374     color = getPixelColor(device, 480, 120);
7375     ok(color == 0x000000ff,
7376        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7377
7378     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7379     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7380
7381     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7382                                              D3DPOOL_MANAGED, &buffer, NULL);
7383     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7384     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7385     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7386     memcpy(data, quad, sizeof(quad));
7387     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7388     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7389     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7390     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7391
7392     hr = IDirect3DDevice9_BeginScene(device);
7393     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7394     if(SUCCEEDED(hr)) {
7395             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7396             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7397             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7398             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7399             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7400             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7401             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7402             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7403
7404             hr = IDirect3DDevice9_EndScene(device);
7405             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7406     }
7407
7408     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7409     color = getPixelColor(device, 480, 360);
7410     ok(color == 0x00ff0000,
7411        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7412     color = getPixelColor(device, 160, 120);
7413     ok(color == 0x00000000,
7414        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7415     color = getPixelColor(device, 160, 360);
7416     ok(color == 0x0000ff00,
7417        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7418     color = getPixelColor(device, 480, 120);
7419     ok(color == 0x000000ff,
7420        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7421
7422     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7423     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7424     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7425     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7426     IDirect3DDevice9_SetVertexShader(device, NULL);
7427     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7428
7429     IDirect3DVertexDeclaration9_Release(vdecl);
7430     IDirect3DVertexShader9_Release(shader);
7431     IDirect3DVertexBuffer9_Release(buffer);
7432 }
7433
7434 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7435 {
7436     D3DCAPS9 caps;
7437     IDirect3DTexture9 *texture;
7438     HRESULT hr;
7439     D3DLOCKED_RECT rect;
7440     unsigned int x, y;
7441     DWORD *dst, color;
7442     const float quad[] = {
7443         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7444          1.0,   -1.0,   0.1,    1.2,   -0.2,
7445         -1.0,    1.0,   0.1,   -0.2,    1.2,
7446          1.0,    1.0,   0.1,    1.2,    1.2
7447     };
7448     memset(&caps, 0, sizeof(caps));
7449
7450     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7451     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7452     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7453         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7454         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7455            "Card has conditional NP2 support without power of two restriction set\n");
7456         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7457         return;
7458     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7459         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7460         return;
7461     }
7462
7463     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7464     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7465
7466     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7467     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7468
7469     memset(&rect, 0, sizeof(rect));
7470     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7471     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7472     for(y = 0; y < 10; y++) {
7473         for(x = 0; x < 10; x++) {
7474             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7475             if(x == 0 || x == 9 || y == 0 || y == 9) {
7476                 *dst = 0x00ff0000;
7477             } else {
7478                 *dst = 0x000000ff;
7479             }
7480         }
7481     }
7482     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7483     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7484
7485     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7486     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7487     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7488     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7489     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7490     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7491     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7492     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7493
7494     hr = IDirect3DDevice9_BeginScene(device);
7495     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7496     if(SUCCEEDED(hr)) {
7497         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7498         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7499
7500         hr = IDirect3DDevice9_EndScene(device);
7501         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7502     }
7503
7504     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7505
7506     color = getPixelColor(device,    1,  1);
7507     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7508     color = getPixelColor(device, 639, 479);
7509     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7510
7511     color = getPixelColor(device, 135, 101);
7512     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7513     color = getPixelColor(device, 140, 101);
7514     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7515     color = getPixelColor(device, 135, 105);
7516     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7517     color = getPixelColor(device, 140, 105);
7518     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7519
7520     color = getPixelColor(device, 135, 376);
7521     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7522     color = getPixelColor(device, 140, 376);
7523     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7524     color = getPixelColor(device, 135, 379);
7525     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7526     color = getPixelColor(device, 140, 379);
7527     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7528
7529     color = getPixelColor(device, 500, 101);
7530     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7531     color = getPixelColor(device, 504, 101);
7532     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7533     color = getPixelColor(device, 500, 105);
7534     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7535     color = getPixelColor(device, 504, 105);
7536     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7537
7538     color = getPixelColor(device, 500, 376);
7539     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7540     color = getPixelColor(device, 504, 376);
7541     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7542     color = getPixelColor(device, 500, 380);
7543     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7544     color = getPixelColor(device, 504, 380);
7545     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7546
7547     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7548     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7549     IDirect3DTexture9_Release(texture);
7550 }
7551
7552 static void vFace_register_test(IDirect3DDevice9 *device)
7553 {
7554     HRESULT hr;
7555     DWORD color;
7556     const DWORD shader_code[] = {
7557         0xffff0300,                                                             /* ps_3_0                     */
7558         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7559         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7560         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7561         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7562         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7563         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7564         0x0000ffff                                                              /* END                        */
7565     };
7566     IDirect3DPixelShader9 *shader;
7567     IDirect3DTexture9 *texture;
7568     IDirect3DSurface9 *surface, *backbuffer;
7569     const float quad[] = {
7570         -1.0,   -1.0,   0.1,
7571          1.0,   -1.0,   0.1,
7572         -1.0,    0.0,   0.1,
7573
7574          1.0,   -1.0,   0.1,
7575          1.0,    0.0,   0.1,
7576         -1.0,    0.0,   0.1,
7577
7578         -1.0,    0.0,   0.1,
7579         -1.0,    1.0,   0.1,
7580          1.0,    0.0,   0.1,
7581
7582          1.0,    0.0,   0.1,
7583         -1.0,    1.0,   0.1,
7584          1.0,    1.0,   0.1,
7585     };
7586     const float blit[] = {
7587          0.0,   -1.0,   0.1,    0.0,    0.0,
7588          1.0,   -1.0,   0.1,    1.0,    0.0,
7589          0.0,    1.0,   0.1,    0.0,    1.0,
7590          1.0,    1.0,   0.1,    1.0,    1.0,
7591     };
7592
7593     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7594     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7595     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7596     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7597     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7598     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7599     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7600     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7601     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7602     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7603     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7604     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7605
7606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7608
7609     hr = IDirect3DDevice9_BeginScene(device);
7610     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7611     if(SUCCEEDED(hr)) {
7612         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7613         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7614         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7615         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7616         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7617         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7618         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7619         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7620         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7621         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7622         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7623
7624         /* Blit the texture onto the back buffer to make it visible */
7625         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7626         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7627         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7628         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7629         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7630         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7631         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7632         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7633         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7634         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7635
7636         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7637         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7638
7639         hr = IDirect3DDevice9_EndScene(device);
7640         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7641     }
7642
7643     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7644     color = getPixelColor(device, 160, 360);
7645     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7646     color = getPixelColor(device, 160, 120);
7647     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7648     color = getPixelColor(device, 480, 360);
7649     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7650     color = getPixelColor(device, 480, 120);
7651     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7652
7653     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7654     IDirect3DDevice9_SetTexture(device, 0, NULL);
7655     IDirect3DPixelShader9_Release(shader);
7656     IDirect3DSurface9_Release(surface);
7657     IDirect3DSurface9_Release(backbuffer);
7658     IDirect3DTexture9_Release(texture);
7659 }
7660
7661 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7662 {
7663     HRESULT hr;
7664     DWORD color;
7665     int i;
7666     D3DCAPS9 caps;
7667     BOOL L6V5U5_supported = FALSE;
7668     IDirect3DTexture9 *tex1, *tex2;
7669     D3DLOCKED_RECT locked_rect;
7670
7671     static const float quad[][7] = {
7672         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7673         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7674         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7675         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7676     };
7677
7678     static const D3DVERTEXELEMENT9 decl_elements[] = {
7679         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7680         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7681         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7682         D3DDECL_END()
7683     };
7684
7685     /* use asymmetric matrix to test loading */
7686     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7687     float scale, offset;
7688
7689     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7690     IDirect3DTexture9           *texture            = NULL;
7691
7692     memset(&caps, 0, sizeof(caps));
7693     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7694     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7695     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7696         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7697         return;
7698     } else {
7699         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7700          * They report that it is not supported, but after that bump mapping works properly. So just test
7701          * if the format is generally supported, and check the BUMPENVMAP flag
7702          */
7703         IDirect3D9 *d3d9;
7704
7705         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7706         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7707                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7708         L6V5U5_supported = SUCCEEDED(hr);
7709         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7710                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7711         IDirect3D9_Release(d3d9);
7712         if(FAILED(hr)) {
7713             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7714             return;
7715         }
7716     }
7717
7718     /* Generate the textures */
7719     generate_bumpmap_textures(device);
7720
7721     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7722     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7723     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7724     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7725     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7726     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7727     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7728     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7729
7730     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7731     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7732     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7733     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7734     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7735     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7736
7737     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7738     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7739     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7740     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7741     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7742     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7743
7744     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7745     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7746
7747     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7748     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7749
7750     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7751     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7752
7753
7754     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7755     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7756     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7757     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7758
7759     hr = IDirect3DDevice9_BeginScene(device);
7760     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7761
7762     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7763     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7764
7765     hr = IDirect3DDevice9_EndScene(device);
7766     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7767
7768     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7769     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7770
7771     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7772      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7773      * But since testing the color match is not the purpose of the test don't be too picky
7774      */
7775     color = getPixelColor(device, 320-32, 240);
7776     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7777     color = getPixelColor(device, 320+32, 240);
7778     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7779     color = getPixelColor(device, 320, 240-32);
7780     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7781     color = getPixelColor(device, 320, 240+32);
7782     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7783     color = getPixelColor(device, 320, 240);
7784     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7785     color = getPixelColor(device, 320+32, 240+32);
7786     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7787     color = getPixelColor(device, 320-32, 240+32);
7788     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7789     color = getPixelColor(device, 320+32, 240-32);
7790     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7791     color = getPixelColor(device, 320-32, 240-32);
7792     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7793
7794     for(i = 0; i < 2; i++) {
7795         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7796         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7797         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7798         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7799         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7800         IDirect3DTexture9_Release(texture); /* To destroy it */
7801     }
7802
7803     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7804         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7805         goto cleanup;
7806     }
7807     if(L6V5U5_supported == FALSE) {
7808         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7809         goto cleanup;
7810     }
7811
7812     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7813     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7814     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7815      * would only make this test more complicated
7816      */
7817     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7818     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7819     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7820     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7821
7822     memset(&locked_rect, 0, sizeof(locked_rect));
7823     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7824     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7825     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7826     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7827     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7828
7829     memset(&locked_rect, 0, sizeof(locked_rect));
7830     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7831     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7832     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7833     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7834     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7835
7836     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7837     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7838     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7839     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7840
7841     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7842     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7843     scale = 2.0;
7844     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7845     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7846     offset = 0.1;
7847     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7848     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7849
7850     hr = IDirect3DDevice9_BeginScene(device);
7851     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7852     if(SUCCEEDED(hr)) {
7853         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7854         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7855         hr = IDirect3DDevice9_EndScene(device);
7856         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7857     }
7858
7859     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7860     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7861     color = getPixelColor(device, 320, 240);
7862     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7863      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7864      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7865      */
7866     ok(color_match(color, 0x00994c72, 3), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7867
7868     /* Check a result scale factor > 1.0 */
7869     scale = 10;
7870     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7871     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7872     offset = 10;
7873     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7874     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7875
7876     hr = IDirect3DDevice9_BeginScene(device);
7877     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7878     if(SUCCEEDED(hr)) {
7879         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7880         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7881         hr = IDirect3DDevice9_EndScene(device);
7882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7883     }
7884     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7885     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7886     color = getPixelColor(device, 320, 240);
7887     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7888
7889     /* Check clamping in the scale factor calculation */
7890     scale = 1000;
7891     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7892     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7893     offset = -1;
7894     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7895     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7896
7897     hr = IDirect3DDevice9_BeginScene(device);
7898     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7899     if(SUCCEEDED(hr)) {
7900         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7901         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7902         hr = IDirect3DDevice9_EndScene(device);
7903         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7904     }
7905     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7906     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7907     color = getPixelColor(device, 320, 240);
7908     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7909
7910     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7911     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7912     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7913     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7914
7915     IDirect3DTexture9_Release(tex1);
7916     IDirect3DTexture9_Release(tex2);
7917
7918 cleanup:
7919     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7920     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7921     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7922     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7923
7924     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7925     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7926     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7927 }
7928
7929 static void stencil_cull_test(IDirect3DDevice9 *device) {
7930     HRESULT hr;
7931     IDirect3DSurface9 *depthstencil = NULL;
7932     D3DSURFACE_DESC desc;
7933     float quad1[] = {
7934         -1.0,   -1.0,   0.1,
7935          0.0,   -1.0,   0.1,
7936         -1.0,    0.0,   0.1,
7937          0.0,    0.0,   0.1,
7938     };
7939     float quad2[] = {
7940          0.0,   -1.0,   0.1,
7941          1.0,   -1.0,   0.1,
7942          0.0,    0.0,   0.1,
7943          1.0,    0.0,   0.1,
7944     };
7945     float quad3[] = {
7946         0.0,    0.0,   0.1,
7947         1.0,    0.0,   0.1,
7948         0.0,    1.0,   0.1,
7949         1.0,    1.0,   0.1,
7950     };
7951     float quad4[] = {
7952         -1.0,    0.0,   0.1,
7953          0.0,    0.0,   0.1,
7954         -1.0,    1.0,   0.1,
7955          0.0,    1.0,   0.1,
7956     };
7957     struct vertex painter[] = {
7958        {-1.0,   -1.0,   0.0,    0x00000000},
7959        { 1.0,   -1.0,   0.0,    0x00000000},
7960        {-1.0,    1.0,   0.0,    0x00000000},
7961        { 1.0,    1.0,   0.0,    0x00000000},
7962     };
7963     WORD indices_cw[]  = {0, 1, 3};
7964     WORD indices_ccw[] = {0, 2, 3};
7965     unsigned int i;
7966     DWORD color;
7967
7968     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7969     if(depthstencil == NULL) {
7970         skip("No depth stencil buffer\n");
7971         return;
7972     }
7973     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7974     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
7975     IDirect3DSurface9_Release(depthstencil);
7976     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7977         skip("No 4 or 8 bit stencil surface\n");
7978         return;
7979     }
7980
7981     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7982     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7983     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7984
7985     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7986     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7987     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7988     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7989     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7990     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7991     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7992     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7993
7994     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7995     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7997     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7998     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7999     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8000
8001     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8002     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8004     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8005
8006     /* First pass: Fill the stencil buffer with some values... */
8007     hr = IDirect3DDevice9_BeginScene(device);
8008     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8009     if(SUCCEEDED(hr))
8010     {
8011         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8012         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8013         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8014                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8015         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8016                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8017
8018         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8019         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8020         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8021         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8022         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8023                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8024         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8025                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8026
8027         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8028         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8029         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8030                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8031         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8032                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8033
8034         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8035         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8036         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8037                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8038         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8039                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8040
8041         hr = IDirect3DDevice9_EndScene(device);
8042         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8043     }
8044
8045     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8046     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8047     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8048     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8049     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8051     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8053     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8055     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8058
8059     /* 2nd pass: Make the stencil values visible */
8060     hr = IDirect3DDevice9_BeginScene(device);
8061     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8062     if(SUCCEEDED(hr))
8063     {
8064         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8065         for(i = 0; i < 16; i++) {
8066             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8067             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8068
8069             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8070             painter[1].diffuse = (i * 16);
8071             painter[2].diffuse = (i * 16);
8072             painter[3].diffuse = (i * 16);
8073             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8074             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8075         }
8076         hr = IDirect3DDevice9_EndScene(device);
8077         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8078     }
8079
8080     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8081     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8082
8083     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8084     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8085
8086     color = getPixelColor(device, 160, 420);
8087     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8088     color = getPixelColor(device, 160, 300);
8089     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8090
8091     color = getPixelColor(device, 480, 420);
8092     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8093     color = getPixelColor(device, 480, 300);
8094     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8095
8096     color = getPixelColor(device, 160, 180);
8097     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8098     color = getPixelColor(device, 160, 60);
8099     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8100
8101     color = getPixelColor(device, 480, 180);
8102     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8103     color = getPixelColor(device, 480, 60);
8104     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8105 }
8106
8107 static void vpos_register_test(IDirect3DDevice9 *device)
8108 {
8109     HRESULT hr;
8110     DWORD color;
8111     const DWORD shader_code[] = {
8112     0xffff0300,                                                             /* ps_3_0                     */
8113     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8114     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8115     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8116     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8117     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8118     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8119     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8120     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8121     0x0000ffff                                                              /* end                        */
8122     };
8123     const DWORD shader_frac_code[] = {
8124     0xffff0300,                                                             /* ps_3_0                     */
8125     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8126     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8127     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8128     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8129     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8130     0x0000ffff                                                              /* end                        */
8131     };
8132     IDirect3DPixelShader9 *shader, *shader_frac;
8133     IDirect3DSurface9 *surface = NULL, *backbuffer;
8134     const float quad[] = {
8135         -1.0,   -1.0,   0.1,    0.0,    0.0,
8136          1.0,   -1.0,   0.1,    1.0,    0.0,
8137         -1.0,    1.0,   0.1,    0.0,    1.0,
8138          1.0,    1.0,   0.1,    1.0,    1.0,
8139     };
8140     D3DLOCKED_RECT lr;
8141     float constant[4] = {1.0, 0.0, 320, 240};
8142     DWORD *pos;
8143
8144     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8145     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8146     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8147     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8148     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8149     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8150     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8151     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8152     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8153     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8154     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8156
8157     hr = IDirect3DDevice9_BeginScene(device);
8158     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8159     if(SUCCEEDED(hr)) {
8160         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8161         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8162         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8163         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8164         hr = IDirect3DDevice9_EndScene(device);
8165         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8166     }
8167
8168     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8169     /* This has to be pixel exact */
8170     color = getPixelColor(device, 319, 239);
8171     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8172     color = getPixelColor(device, 320, 239);
8173     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8174     color = getPixelColor(device, 319, 240);
8175     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8176     color = getPixelColor(device, 320, 240);
8177     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8178
8179     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8180                                              &surface, NULL);
8181     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8182     hr = IDirect3DDevice9_BeginScene(device);
8183     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8184     if(SUCCEEDED(hr)) {
8185         constant[2] = 16; constant[3] = 16;
8186         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8187         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8188         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8189         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8191         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8192         hr = IDirect3DDevice9_EndScene(device);
8193         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8194     }
8195     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8196     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8197
8198     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8199     color = *pos & 0x00ffffff;
8200     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8201     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8202     color = *pos & 0x00ffffff;
8203     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8204     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8205     color = *pos & 0x00ffffff;
8206     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8207     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8208     color = *pos & 0x00ffffff;
8209     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8210
8211     hr = IDirect3DSurface9_UnlockRect(surface);
8212     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8213
8214     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8215      * have full control over the multisampling setting inside this test
8216      */
8217     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8218     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8219     hr = IDirect3DDevice9_BeginScene(device);
8220     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8221     if(SUCCEEDED(hr)) {
8222         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8223         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8225         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8226         hr = IDirect3DDevice9_EndScene(device);
8227         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8228     }
8229     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8230     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8231
8232     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8233     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8234
8235     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8236     color = *pos & 0x00ffffff;
8237     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8238
8239     hr = IDirect3DSurface9_UnlockRect(surface);
8240     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8241
8242     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8243     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8244     IDirect3DPixelShader9_Release(shader);
8245     IDirect3DPixelShader9_Release(shader_frac);
8246     if(surface) IDirect3DSurface9_Release(surface);
8247     IDirect3DSurface9_Release(backbuffer);
8248 }
8249
8250 static void pointsize_test(IDirect3DDevice9 *device)
8251 {
8252     HRESULT hr;
8253     D3DCAPS9 caps;
8254     D3DMATRIX matrix;
8255     D3DMATRIX identity;
8256     float ptsize, ptsize_orig;
8257     DWORD color;
8258
8259     const float vertices[] = {
8260         64,     64,     0.1,
8261         128,    64,     0.1,
8262         192,    64,     0.1,
8263         256,    64,     0.1,
8264         320,    64,     0.1,
8265         384,    64,     0.1
8266     };
8267
8268     /* 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 */
8269     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;
8270     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;
8271     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;
8272     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;
8273
8274     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;
8275     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;
8276     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;
8277     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;
8278
8279     memset(&caps, 0, sizeof(caps));
8280     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8281     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8282     if(caps.MaxPointSize < 32.0) {
8283         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8284         return;
8285     }
8286
8287     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8288     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8289     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8290     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8291     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8292     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8293     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8294     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8295
8296     hr = IDirect3DDevice9_BeginScene(device);
8297     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8298     if(SUCCEEDED(hr)) {
8299         ptsize = 16.0;
8300         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8301         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8302         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8303         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8304
8305         ptsize = 32.0;
8306         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8307         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8308         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8309         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8310
8311         ptsize = 31.5;
8312         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8313         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8314         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8315         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8316
8317         if(caps.MaxPointSize >= 64.0) {
8318             ptsize = 64.0;
8319             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8320             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8321             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8322             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8323
8324             ptsize = 63.75;
8325             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8326             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8327             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8328             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8329         }
8330
8331         ptsize = 1.0;
8332         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8333         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8334         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8335         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8336
8337         hr = IDirect3DDevice9_EndScene(device);
8338         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8339     }
8340     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8341     color = getPixelColor(device, 64-9, 64-9);
8342     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8343     color = getPixelColor(device, 64-8, 64-8);
8344     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8345     color = getPixelColor(device, 64-7, 64-7);
8346     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8347     color = getPixelColor(device, 64+7, 64+7);
8348     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8349     color = getPixelColor(device, 64+8, 64+8);
8350     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8351     color = getPixelColor(device, 64+9, 64+9);
8352     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8353
8354     color = getPixelColor(device, 128-17, 64-17);
8355     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8356     color = getPixelColor(device, 128-16, 64-16);
8357     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8358     color = getPixelColor(device, 128-15, 64-15);
8359     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8360     color = getPixelColor(device, 128+15, 64+15);
8361     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8362     color = getPixelColor(device, 128+16, 64+16);
8363     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8364     color = getPixelColor(device, 128+17, 64+17);
8365     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8366
8367     color = getPixelColor(device, 192-17, 64-17);
8368     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8369     color = getPixelColor(device, 192-16, 64-16);
8370     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8371     color = getPixelColor(device, 192-15, 64-15);
8372     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8373     color = getPixelColor(device, 192+15, 64+15);
8374     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8375     color = getPixelColor(device, 192+16, 64+16);
8376     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8377     color = getPixelColor(device, 192+17, 64+17);
8378     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8379
8380     if(caps.MaxPointSize >= 64.0) {
8381         color = getPixelColor(device, 256-33, 64-33);
8382         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8383         color = getPixelColor(device, 256-32, 64-32);
8384         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8385         color = getPixelColor(device, 256-31, 64-31);
8386         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8387         color = getPixelColor(device, 256+31, 64+31);
8388         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8389         color = getPixelColor(device, 256+32, 64+32);
8390         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8391         color = getPixelColor(device, 256+33, 64+33);
8392         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8393
8394         color = getPixelColor(device, 384-33, 64-33);
8395         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8396         color = getPixelColor(device, 384-32, 64-32);
8397         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8398         color = getPixelColor(device, 384-31, 64-31);
8399         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8400         color = getPixelColor(device, 384+31, 64+31);
8401         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8402         color = getPixelColor(device, 384+32, 64+32);
8403         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8404         color = getPixelColor(device, 384+33, 64+33);
8405         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8406     }
8407
8408     color = getPixelColor(device, 320-1, 64-1);
8409     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8410     color = getPixelColor(device, 320-0, 64-0);
8411     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8412     color = getPixelColor(device, 320+1, 64+1);
8413     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8414
8415     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8416     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8417     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8418     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8419 }
8420
8421 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8422 {
8423     HRESULT hr;
8424     IDirect3DPixelShader9 *ps;
8425     IDirect3DTexture9 *tex1, *tex2;
8426     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8427     D3DCAPS9 caps;
8428     DWORD color;
8429     DWORD shader_code[] = {
8430     0xffff0300,                                                             /* ps_3_0             */
8431     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8432     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8433     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8434     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8435     0x0000ffff                                                              /* END                */
8436     };
8437     float quad[] = {
8438        -1.0,   -1.0,    0.1,
8439         1.0,   -1.0,    0.1,
8440        -1.0,    1.0,    0.1,
8441         1.0,    1.0,    0.1,
8442     };
8443     float texquad[] = {
8444        -1.0,   -1.0,    0.1,    0.0,    0.0,
8445         0.0,   -1.0,    0.1,    1.0,    0.0,
8446        -1.0,    1.0,    0.1,    0.0,    1.0,
8447         0.0,    1.0,    0.1,    1.0,    1.0,
8448
8449         0.0,   -1.0,    0.1,    0.0,    0.0,
8450         1.0,   -1.0,    0.1,    1.0,    0.0,
8451         0.0,    1.0,    0.1,    0.0,    1.0,
8452         1.0,    1.0,    0.1,    1.0,    1.0,
8453     };
8454
8455     memset(&caps, 0, sizeof(caps));
8456     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8457     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8458     if(caps.NumSimultaneousRTs < 2) {
8459         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8460         return;
8461     }
8462
8463     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8464     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8465
8466     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8467     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8468     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8469     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8470     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8471     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8472
8473     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8474     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8475     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8476     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8477     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8478     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8479
8480     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8481     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8482     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8483     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8484     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8485     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8486     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8487     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8488
8489     hr = IDirect3DDevice9_BeginScene(device);
8490     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8491     if(SUCCEEDED(hr)) {
8492         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8493         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8494
8495         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8496         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8497         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8498         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8499         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8500         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8501         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8502         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8503
8504         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8505         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8507         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8508
8509         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8510         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8511         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8512         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8513
8514         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8515         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8516
8517         hr = IDirect3DDevice9_EndScene(device);
8518         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8519     }
8520
8521     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8522     color = getPixelColor(device, 160, 240);
8523     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8524     color = getPixelColor(device, 480, 240);
8525     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8526
8527     IDirect3DPixelShader9_Release(ps);
8528     IDirect3DTexture9_Release(tex1);
8529     IDirect3DTexture9_Release(tex2);
8530     IDirect3DSurface9_Release(surf1);
8531     IDirect3DSurface9_Release(surf2);
8532     IDirect3DSurface9_Release(backbuf);
8533 }
8534
8535 struct formats {
8536     const char *fmtName;
8537     D3DFORMAT textureFormat;
8538     DWORD resultColorBlending;
8539     DWORD resultColorNoBlending;
8540 };
8541
8542 const struct formats test_formats[] = {
8543   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8544   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8545   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8546   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8547   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8548   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8549   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8550   { NULL, 0 }
8551 };
8552
8553 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8554 {
8555     HRESULT hr;
8556     IDirect3DTexture9 *offscreenTexture = NULL;
8557     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8558     IDirect3D9 *d3d = NULL;
8559     DWORD color;
8560     DWORD r0, g0, b0, r1, g1, b1;
8561     int fmt_index;
8562
8563     static const float quad[][5] = {
8564         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8565         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8566         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8567         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8568     };
8569
8570     /* Quad with R=0x10, G=0x20 */
8571     static const struct vertex quad1[] = {
8572         {-1.0f, -1.0f, 0.1f, 0x80102000},
8573         {-1.0f,  1.0f, 0.1f, 0x80102000},
8574         { 1.0f, -1.0f, 0.1f, 0x80102000},
8575         { 1.0f,  1.0f, 0.1f, 0x80102000},
8576     };
8577
8578     /* Quad with R=0x20, G=0x10 */
8579     static const struct vertex quad2[] = {
8580         {-1.0f, -1.0f, 0.1f, 0x80201000},
8581         {-1.0f,  1.0f, 0.1f, 0x80201000},
8582         { 1.0f, -1.0f, 0.1f, 0x80201000},
8583         { 1.0f,  1.0f, 0.1f, 0x80201000},
8584     };
8585
8586     IDirect3DDevice9_GetDirect3D(device, &d3d);
8587
8588     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8589     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8590     if(!backbuffer) {
8591         goto out;
8592     }
8593
8594     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8595     {
8596         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8597         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8598            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8599            continue;
8600         }
8601
8602         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8603         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8604
8605         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8606         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8607         if(!offscreenTexture) {
8608             continue;
8609         }
8610
8611         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8612         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8613         if(!offscreen) {
8614             continue;
8615         }
8616
8617         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8618         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8619
8620         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8621         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8622         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8623         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8624         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8625         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8626         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8627         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8628         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8629         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8630
8631         /* Below we will draw two quads with different colors and try to blend them together.
8632          * The result color is compared with the expected outcome.
8633          */
8634         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8635             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8636             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8637             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8638             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8639
8640             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8641             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8642
8643             /* Draw a quad using color 0x0010200 */
8644             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8645             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8646             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8647             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8648             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8649             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8650
8651             /* Draw a quad using color 0x0020100 */
8652             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8653             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8654             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8655             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8656             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8657             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8658
8659             /* We don't want to blend the result on the backbuffer */
8660             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8661             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8662
8663             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8664             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8665             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8666             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8667             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8668
8669             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8670             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8671
8672             /* This time with the texture */
8673             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8674             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8675
8676             IDirect3DDevice9_EndScene(device);
8677         }
8678         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8679
8680
8681         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8682             /* Compare the color of the center quad with our expectation */
8683             color = getPixelColor(device, 320, 240);
8684             r0 = (color & 0x00ff0000) >> 16;
8685             g0 = (color & 0x0000ff00) >>  8;
8686             b0 = (color & 0x000000ff) >>  0;
8687
8688             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8689             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8690             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8691
8692             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8693                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8694                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8695                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8696         } else {
8697             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8698              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8699              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8700             color = getPixelColor(device, 320, 240);
8701             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);
8702         }
8703
8704         IDirect3DDevice9_SetTexture(device, 0, NULL);
8705         if(offscreenTexture) {
8706             IDirect3DTexture9_Release(offscreenTexture);
8707         }
8708         if(offscreen) {
8709             IDirect3DSurface9_Release(offscreen);
8710         }
8711     }
8712
8713 out:
8714     /* restore things */
8715     if(backbuffer) {
8716         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8717         IDirect3DSurface9_Release(backbuffer);
8718     }
8719 }
8720
8721 static void tssargtemp_test(IDirect3DDevice9 *device)
8722 {
8723     HRESULT hr;
8724     DWORD color;
8725     static const struct vertex quad[] = {
8726         {-1.0,     -1.0,    0.1,    0x00ff0000},
8727         { 1.0,     -1.0,    0.1,    0x00ff0000},
8728         {-1.0,      1.0,    0.1,    0x00ff0000},
8729         { 1.0,      1.0,    0.1,    0x00ff0000}
8730     };
8731     D3DCAPS9 caps;
8732
8733     memset(&caps, 0, sizeof(caps));
8734     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8735     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8736     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8737         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8738         return;
8739     }
8740
8741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8742     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8743
8744     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8745     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8746     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8747     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8748
8749     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8750     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8751     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8752     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8753     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8754     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8755
8756     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8757     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8758     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8759     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8760     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8761     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8762
8763     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8764     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8765
8766     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8767     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8768     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8769     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8770
8771     hr = IDirect3DDevice9_BeginScene(device);
8772     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8773     if(SUCCEEDED(hr)) {
8774
8775         hr = IDirect3DDevice9_EndScene(device);
8776         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8778         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8779     }
8780     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8781     color = getPixelColor(device, 320, 240);
8782     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8783
8784     /* Set stage 1 back to default */
8785     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8786     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8787     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8788     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8789     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8790     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8791     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8792     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8793     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8794     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8795 }
8796
8797 struct testdata
8798 {
8799     DWORD idxVertex; /* number of instances in the first stream */
8800     DWORD idxColor; /* number of instances in the second stream */
8801     DWORD idxInstance; /* should be 1 ?? */
8802     DWORD color1; /* color 1 instance */
8803     DWORD color2; /* color 2 instance */
8804     DWORD color3; /* color 3 instance */
8805     DWORD color4; /* color 4 instance */
8806     WORD strVertex; /* specify which stream to use 0-2*/
8807     WORD strColor;
8808     WORD strInstance;
8809 };
8810
8811 static const struct testdata testcases[]=
8812 {
8813     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8814     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8815     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8816     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8817     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8818     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8819     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8820     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8821     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8822     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8823     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8824     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8825     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8826     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8827     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8828 /*
8829     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8830     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8831 */
8832 };
8833
8834 /* Drawing Indexed Geometry with instances*/
8835 static void stream_test(IDirect3DDevice9 *device)
8836 {
8837     IDirect3DVertexBuffer9 *vb = NULL;
8838     IDirect3DVertexBuffer9 *vb2 = NULL;
8839     IDirect3DVertexBuffer9 *vb3 = NULL;
8840     IDirect3DIndexBuffer9 *ib = NULL;
8841     IDirect3DVertexDeclaration9 *pDecl = NULL;
8842     IDirect3DVertexShader9 *shader = NULL;
8843     HRESULT hr;
8844     BYTE *data;
8845     DWORD color;
8846     DWORD ind;
8847     unsigned i;
8848
8849     const DWORD shader_code[] =
8850     {
8851         0xfffe0101,                                     /* vs_1_1 */
8852         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
8853         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
8854         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
8855         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
8856         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8857         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
8858         0x0000ffff
8859     };
8860
8861     const float quad[][3] =
8862     {
8863         {-0.5f, -0.5f,  1.1f}, /*0 */
8864         {-0.5f,  0.5f,  1.1f}, /*1 */
8865         { 0.5f, -0.5f,  1.1f}, /*2 */
8866         { 0.5f,  0.5f,  1.1f}, /*3 */
8867     };
8868
8869     const float vertcolor[][4] =
8870     {
8871         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8872         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8873         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8874         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8875     };
8876
8877     /* 4 position for 4 instances */
8878     const float instancepos[][3] =
8879     {
8880         {-0.6f,-0.6f, 0.0f},
8881         { 0.6f,-0.6f, 0.0f},
8882         { 0.6f, 0.6f, 0.0f},
8883         {-0.6f, 0.6f, 0.0f},
8884     };
8885
8886     short indices[] = {0, 1, 2, 1, 2, 3};
8887
8888     D3DVERTEXELEMENT9 decl[] =
8889     {
8890         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8891         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8892         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8893         D3DDECL_END()
8894     };
8895
8896     /* set the default value because it isn't done in wine? */
8897     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8898     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8899
8900     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8901     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8902     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8903
8904     /* check wrong cases */
8905     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8906     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8907     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8908     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8909     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8910     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8911     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8912     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8913     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8914     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8915     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8916     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8917     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8918     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8919     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8920     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8921     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8922     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8923     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8924     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8925
8926     /* set the default value back */
8927     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8928     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8929
8930     /* create all VertexBuffers*/
8931     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8932     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8933     if(!vb) {
8934         skip("Failed to create a vertex buffer\n");
8935         return;
8936     }
8937     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8938     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8939     if(!vb2) {
8940         skip("Failed to create a vertex buffer\n");
8941         goto out;
8942     }
8943     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8944     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8945     if(!vb3) {
8946         skip("Failed to create a vertex buffer\n");
8947         goto out;
8948     }
8949
8950     /* create IndexBuffer*/
8951     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8952     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
8953     if(!ib) {
8954         skip("Failed to create a index buffer\n");
8955         goto out;
8956     }
8957
8958     /* copy all Buffers (Vertex + Index)*/
8959     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8960     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8961     memcpy(data, quad, sizeof(quad));
8962     hr = IDirect3DVertexBuffer9_Unlock(vb);
8963     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8964     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8965     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8966     memcpy(data, vertcolor, sizeof(vertcolor));
8967     hr = IDirect3DVertexBuffer9_Unlock(vb2);
8968     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8969     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8970     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8971     memcpy(data, instancepos, sizeof(instancepos));
8972     hr = IDirect3DVertexBuffer9_Unlock(vb3);
8973     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8974     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8975     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
8976     memcpy(data, indices, sizeof(indices));
8977     hr = IDirect3DIndexBuffer9_Unlock(ib);
8978     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8979
8980     /* create VertexShader */
8981     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8982     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8983     if(!shader) {
8984         skip("Failed to create a vetex shader\n");
8985         goto out;
8986     }
8987
8988     hr = IDirect3DDevice9_SetVertexShader(device, shader);
8989     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8990
8991     hr = IDirect3DDevice9_SetIndices(device, ib);
8992     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8993
8994     /* run all tests */
8995     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8996     {
8997         struct testdata act = testcases[i];
8998         decl[0].Stream = act.strVertex;
8999         decl[1].Stream = act.strColor;
9000         decl[2].Stream = act.strInstance;
9001         /* create VertexDeclarations */
9002         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9003         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9004
9005         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9006         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9007
9008         hr = IDirect3DDevice9_BeginScene(device);
9009         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9010         if(SUCCEEDED(hr))
9011         {
9012             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9013             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9014
9015             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9016             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9017             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9018             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9019
9020             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9021             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9022             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9023             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9024
9025             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9026             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9027             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9028             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9029
9030             /* don't know if this is right (1*3 and 4*1)*/
9031             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9032             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9033             hr = IDirect3DDevice9_EndScene(device);
9034             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9035
9036             /* set all StreamSource && StreamSourceFreq back to default */
9037             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9038             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9039             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9040             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9041             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9042             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9043             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9044             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9045             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9046             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9047             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9048             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9049         }
9050
9051         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9052         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9053
9054         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9055         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9056
9057         color = getPixelColor(device, 160, 360);
9058         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9059         color = getPixelColor(device, 480, 360);
9060         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9061         color = getPixelColor(device, 480, 120);
9062         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9063         color = getPixelColor(device, 160, 120);
9064         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9065     }
9066
9067     hr = IDirect3DDevice9_SetIndices(device, NULL);
9068     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9069
9070 out:
9071     if(vb) IDirect3DVertexBuffer9_Release(vb);
9072     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9073     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9074     if(ib)IDirect3DIndexBuffer9_Release(ib);
9075     if(shader)IDirect3DVertexShader9_Release(shader);
9076 }
9077
9078 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9079     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9080     IDirect3DTexture9 *dsttex = NULL;
9081     HRESULT hr;
9082     DWORD color;
9083     D3DRECT r1 = {0,  0,  50,  50 };
9084     D3DRECT r2 = {50, 0,  100, 50 };
9085     D3DRECT r3 = {50, 50, 100, 100};
9086     D3DRECT r4 = {0,  50,  50, 100};
9087     const float quad[] = {
9088         -1.0,   -1.0,   0.1,    0.0,    0.0,
9089          1.0,   -1.0,   0.1,    1.0,    0.0,
9090         -1.0,    1.0,   0.1,    0.0,    1.0,
9091          1.0,    1.0,   0.1,    1.0,    1.0,
9092     };
9093
9094     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9095     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9096
9097     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9098     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9099     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9100     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9101
9102     if(!src || !dsttex) {
9103         skip("One or more test resources could not be created\n");
9104         goto cleanup;
9105     }
9106
9107     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9108     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9109
9110     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9111     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9112
9113     /* Clear the StretchRect destination for debugging */
9114     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9115     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9116     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9117     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9118
9119     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9120     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9121
9122     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9123     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9124     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9125     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9126     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9127     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9128     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9129     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9130
9131     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9132      * the target -> texture GL blit path
9133      */
9134     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9135     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9136     IDirect3DSurface9_Release(dst);
9137
9138     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9140
9141     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9142     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9143     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9144     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9145     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9146     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9147     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9148     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9149
9150     hr = IDirect3DDevice9_BeginScene(device);
9151     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9152     if(SUCCEEDED(hr)) {
9153         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9154         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9155         hr = IDirect3DDevice9_EndScene(device);
9156         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9157     }
9158
9159     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9160     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9161     color = getPixelColor(device, 160, 360);
9162     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9163     color = getPixelColor(device, 480, 360);
9164     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9165     color = getPixelColor(device, 480, 120);
9166     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9167     color = getPixelColor(device, 160, 120);
9168     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9169
9170     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9171     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9172     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9173     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9174
9175 cleanup:
9176     if(src) IDirect3DSurface9_Release(src);
9177     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9178     if(dsttex) IDirect3DTexture9_Release(dsttex);
9179 }
9180
9181 static void texop_test(IDirect3DDevice9 *device)
9182 {
9183     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9184     IDirect3DTexture9 *texture = NULL;
9185     D3DLOCKED_RECT locked_rect;
9186     D3DCOLOR color;
9187     D3DCAPS9 caps;
9188     HRESULT hr;
9189     unsigned i;
9190
9191     static const struct {
9192         float x, y, z;
9193         float s, t;
9194         D3DCOLOR diffuse;
9195     } quad[] = {
9196         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9197         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9198         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9199         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9200     };
9201
9202     static const D3DVERTEXELEMENT9 decl_elements[] = {
9203         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9204         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9205         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9206         D3DDECL_END()
9207     };
9208
9209     static const struct {
9210         D3DTEXTUREOP op;
9211         const char *name;
9212         DWORD caps_flag;
9213         D3DCOLOR result;
9214     } test_data[] = {
9215         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9216         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9217         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9218         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9219         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9220         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9221         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9222         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9223         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9224         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9225         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9226         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9227         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9228         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9229         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9230         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9231         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9232         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9233         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9234         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9235         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9236         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9237         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9238     };
9239
9240     memset(&caps, 0, sizeof(caps));
9241     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9242     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9243
9244     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9245     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9246     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9247     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9248
9249     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9250     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9251     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9252     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9253     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9254     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9255     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9256     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9257     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9258
9259     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9260     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9261     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9262     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9263     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9264     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9265
9266     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9267     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9268
9269     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9270     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9271     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9272     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9273     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9274     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9275
9276     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9277     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9278
9279     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9280     {
9281         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9282         {
9283             skip("tex operation %s not supported\n", test_data[i].name);
9284             continue;
9285         }
9286
9287         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9288         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9289
9290         hr = IDirect3DDevice9_BeginScene(device);
9291         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9292
9293         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9294         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9295
9296         hr = IDirect3DDevice9_EndScene(device);
9297         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9298
9299         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9300         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9301
9302         color = getPixelColor(device, 320, 240);
9303         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9304                 test_data[i].name, color, test_data[i].result);
9305     }
9306
9307     if (texture) IDirect3DTexture9_Release(texture);
9308     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9309 }
9310
9311 static void yuv_color_test(IDirect3DDevice9 *device) {
9312     HRESULT hr;
9313     IDirect3DSurface9 *surface = NULL, *target = NULL;
9314     unsigned int fmt, i;
9315     D3DFORMAT format;
9316     const char *fmt_string;
9317     D3DLOCKED_RECT lr;
9318     IDirect3D9 *d3d;
9319     HRESULT color;
9320     DWORD ref_color_left, ref_color_right;
9321
9322     struct {
9323         DWORD in;           /* The input color */
9324         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9325         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9326         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9327         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9328     } test_data[] = {
9329     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9330      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9331      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9332      * that
9333      */
9334       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9335       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9336       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9337       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9338       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9339       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9340       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9341       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9342       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9343       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9344       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9345       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9346       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9347       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9348
9349       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9350       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9351       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9352       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9353     };
9354
9355     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9356     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9357     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9358     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9359
9360     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9361     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9362
9363     for(fmt = 0; fmt < 2; fmt++) {
9364         if(fmt == 0) {
9365             format = D3DFMT_UYVY;
9366             fmt_string = "D3DFMT_UYVY";
9367         } else {
9368             format = D3DFMT_YUY2;
9369             fmt_string = "D3DFMT_YUY2";
9370         }
9371
9372         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9373                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9374                        */
9375         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9376                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9377             skip("%s is not supported\n", fmt_string);
9378             continue;
9379         }
9380
9381         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9382         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9383         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9384
9385         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9386             if(fmt == 0) {
9387                 ref_color_left = test_data[i].uyvy_left;
9388                 ref_color_right = test_data[i].uyvy_right;
9389             } else {
9390                 ref_color_left = test_data[i].yuy2_left;
9391                 ref_color_right = test_data[i].yuy2_right;
9392             }
9393
9394             memset(&lr, 0, sizeof(lr));
9395             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9396             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9397             *((DWORD *) lr.pBits) = test_data[i].in;
9398             hr = IDirect3DSurface9_UnlockRect(surface);
9399             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9400
9401             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9402             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9403             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9404             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9405             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9406             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9407
9408             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9409              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9410              * want to add tests for the filtered pixels as well.
9411              *
9412              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9413              * differently, so we need a max diff of 16
9414              */
9415             color = getPixelColor(device, 40, 240);
9416             ok(color_match(color, ref_color_left, 16),
9417                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9418                test_data[i].in, color, ref_color_left, fmt_string);
9419             color = getPixelColor(device, 600, 240);
9420             ok(color_match(color, ref_color_right, 16),
9421                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9422                test_data[i].in, color, ref_color_left, fmt_string);
9423         }
9424         IDirect3DSurface9_Release(surface);
9425     }
9426     IDirect3DSurface9_Release(target);
9427     IDirect3D9_Release(d3d);
9428 }
9429
9430 static void texop_range_test(IDirect3DDevice9 *device)
9431 {
9432     static const struct {
9433         float x, y, z;
9434         D3DCOLOR diffuse;
9435     } quad[] = {
9436         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9437         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9438         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9439         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9440     };
9441     HRESULT hr;
9442     IDirect3DTexture9 *texture;
9443     D3DLOCKED_RECT locked_rect;
9444     D3DCAPS9 caps;
9445     DWORD color;
9446
9447     /* We need ADD and SUBTRACT operations */
9448     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9449     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9450     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9451         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9452     }
9453     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9454         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9455     }
9456
9457     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9458     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9459     /* Stage 1: result = diffuse(=1.0) + diffuse
9460      * stage 2: result = result - tfactor(= 0.5)
9461      */
9462     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9463     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9464     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9465     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9466     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9467     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9468     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9469     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9470     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9471     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9472     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9473     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9474     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9475     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9476
9477     hr = IDirect3DDevice9_BeginScene(device);
9478     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9479     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9480     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9481     hr = IDirect3DDevice9_EndScene(device);
9482     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9483     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9484     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9485
9486     color = getPixelColor(device, 320, 240);
9487     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9488        color);
9489
9490     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9491     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9492     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9493     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9494     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9495     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9496     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9497     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9498     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9499
9500     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9501      * stage 2: result = result + diffuse(1.0)
9502      */
9503     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9504     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9505     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9506     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9507     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9508     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9509     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9510     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9511     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9512     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9513     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9514     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9515     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9516     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9517
9518     hr = IDirect3DDevice9_BeginScene(device);
9519     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9520     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9521     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9522     hr = IDirect3DDevice9_EndScene(device);
9523     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9524     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9525     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9526
9527     color = getPixelColor(device, 320, 240);
9528     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9529        color);
9530
9531     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9532     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9533     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9534     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9535     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)NULL);
9536     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9537     IDirect3DTexture9_Release(texture);
9538 }
9539
9540 static void alphareplicate_test(IDirect3DDevice9 *device) {
9541     struct vertex quad[] = {
9542         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9543         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9544         { -1.0,     1.0,    0.1,    0x80ff00ff },
9545         {  1.0,     1.0,    0.1,    0x80ff00ff },
9546     };
9547     HRESULT hr;
9548     DWORD color;
9549
9550     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9551     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9552
9553     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9554     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9555
9556     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9557     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9558     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9559     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9560
9561     hr = IDirect3DDevice9_BeginScene(device);
9562     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9563     if(SUCCEEDED(hr)) {
9564         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9565         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9566         hr = IDirect3DDevice9_EndScene(device);
9567         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9568     }
9569
9570     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9571     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9572
9573     color = getPixelColor(device, 320, 240);
9574     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9575        color);
9576
9577     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9578     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9579
9580 }
9581
9582 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9583     HRESULT hr;
9584     D3DCAPS9 caps;
9585     DWORD color;
9586     struct vertex quad[] = {
9587         { -1.0,    -1.0,    0.1,    0x408080c0 },
9588         {  1.0,    -1.0,    0.1,    0x408080c0 },
9589         { -1.0,     1.0,    0.1,    0x408080c0 },
9590         {  1.0,     1.0,    0.1,    0x408080c0 },
9591     };
9592
9593     memset(&caps, 0, sizeof(caps));
9594     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9595     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9596     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9597         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9598         return;
9599     }
9600
9601     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9602     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9603
9604     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9605     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9606
9607     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9608      * mov r0.a, diffuse.a
9609      * mov r0, r0.a
9610      *
9611      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9612      * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
9613      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9614      */
9615     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9616     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9617     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9618     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9619     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9620     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9621     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9622     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9623     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9624     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9625     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9626     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9627     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9628     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9629     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9630     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9632     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9633
9634     hr = IDirect3DDevice9_BeginScene(device);
9635     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9636     if(SUCCEEDED(hr)) {
9637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9638         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9639         hr = IDirect3DDevice9_EndScene(device);
9640         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9641     }
9642
9643     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9644     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9645
9646     color = getPixelColor(device, 320, 240);
9647     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9648        color);
9649
9650     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9651     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9652     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9653     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9654     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9655     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9656 }
9657
9658 static void zwriteenable_test(IDirect3DDevice9 *device) {
9659     HRESULT hr;
9660     DWORD color;
9661     struct vertex quad1[] = {
9662         { -1.0,  -1.0,  0.1,    0x00ff0000},
9663         { -1.0,   1.0,  0.1,    0x00ff0000},
9664         {  1.0,  -1.0,  0.1,    0x00ff0000},
9665         {  1.0,   1.0,  0.1,    0x00ff0000},
9666     };
9667     struct vertex quad2[] = {
9668         { -1.0,  -1.0,  0.9,    0x0000ff00},
9669         { -1.0,   1.0,  0.9,    0x0000ff00},
9670         {  1.0,  -1.0,  0.9,    0x0000ff00},
9671         {  1.0,   1.0,  0.9,    0x0000ff00},
9672     };
9673
9674     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9675     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9676
9677     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9678     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9679     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9680     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9681     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9682     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9683     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9684     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9685
9686     hr = IDirect3DDevice9_BeginScene(device);
9687     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9688     if(SUCCEEDED(hr)) {
9689         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9690          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9691          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9692          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9693          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9694          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9695          */
9696         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9697         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9698         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9699         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9700         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9701         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9702
9703         hr = IDirect3DDevice9_EndScene(device);
9704         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9705     }
9706
9707     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9708     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9709     color = getPixelColor(device, 320, 240);
9710     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9711        color);
9712
9713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9714     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9715 }
9716
9717 START_TEST(visual)
9718 {
9719     IDirect3DDevice9 *device_ptr;
9720     D3DCAPS9 caps;
9721     HRESULT hr;
9722     DWORD color;
9723
9724     d3d9_handle = LoadLibraryA("d3d9.dll");
9725     if (!d3d9_handle)
9726     {
9727         skip("Could not load d3d9.dll\n");
9728         return;
9729     }
9730
9731     device_ptr = init_d3d9();
9732     if (!device_ptr)
9733     {
9734         skip("Creating the device failed\n");
9735         return;
9736     }
9737
9738     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9739
9740     /* Check for the reliability of the returned data */
9741     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9742     if(FAILED(hr))
9743     {
9744         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9745         goto cleanup;
9746     }
9747     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9748
9749     color = getPixelColor(device_ptr, 1, 1);
9750     if(color !=0x00ff0000)
9751     {
9752         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9753         goto cleanup;
9754     }
9755
9756     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9757     if(FAILED(hr))
9758     {
9759         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9760         goto cleanup;
9761     }
9762     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9763
9764     color = getPixelColor(device_ptr, 639, 479);
9765     if(color != 0x0000ddee)
9766     {
9767         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9768         goto cleanup;
9769     }
9770
9771     /* Now execute the real tests */
9772     stretchrect_test(device_ptr);
9773     lighting_test(device_ptr);
9774     clear_test(device_ptr);
9775     fog_test(device_ptr);
9776     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9777     {
9778         test_cube_wrap(device_ptr);
9779     } else {
9780         skip("No cube texture support\n");
9781     }
9782     z_range_test(device_ptr);
9783     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9784     {
9785         maxmip_test(device_ptr);
9786     }
9787     else
9788     {
9789         skip("No mipmap support\n");
9790     }
9791     offscreen_test(device_ptr);
9792     alpha_test(device_ptr);
9793     shademode_test(device_ptr);
9794     srgbtexture_test(device_ptr);
9795     release_buffer_test(device_ptr);
9796     float_texture_test(device_ptr);
9797     g16r16_texture_test(device_ptr);
9798     pixelshader_blending_test(device_ptr);
9799     texture_transform_flags_test(device_ptr);
9800     autogen_mipmap_test(device_ptr);
9801     fixed_function_decl_test(device_ptr);
9802     conditional_np2_repeat_test(device_ptr);
9803     fixed_function_bumpmap_test(device_ptr);
9804     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9805         stencil_cull_test(device_ptr);
9806     } else {
9807         skip("No two sided stencil support\n");
9808     }
9809     pointsize_test(device_ptr);
9810     tssargtemp_test(device_ptr);
9811     np2_stretch_rect_test(device_ptr);
9812     yuv_color_test(device_ptr);
9813     zwriteenable_test(device_ptr);
9814
9815     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9816     {
9817         test_constant_clamp_vs(device_ptr);
9818         test_compare_instructions(device_ptr);
9819     }
9820     else skip("No vs_1_1 support\n");
9821
9822     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9823     {
9824         test_mova(device_ptr);
9825         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9826             test_vshader_input(device_ptr);
9827             test_vshader_float16(device_ptr);
9828             stream_test(device_ptr);
9829         } else {
9830             skip("No vs_3_0 support\n");
9831         }
9832     }
9833     else skip("No vs_2_0 support\n");
9834
9835     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9836     {
9837         fog_with_shader_test(device_ptr);
9838         fog_srgbwrite_test(device_ptr);
9839     }
9840     else skip("No vs_1_1 and ps_1_1 support\n");
9841
9842     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9843     {
9844         texbem_test(device_ptr);
9845         texdepth_test(device_ptr);
9846         texkill_test(device_ptr);
9847         x8l8v8u8_test(device_ptr);
9848         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9849             constant_clamp_ps_test(device_ptr);
9850             cnd_test(device_ptr);
9851             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9852                 dp2add_ps_test(device_ptr);
9853                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9854                     nested_loop_test(device_ptr);
9855                     fixed_function_varying_test(device_ptr);
9856                     vFace_register_test(device_ptr);
9857                     vpos_register_test(device_ptr);
9858                     multiple_rendertargets_test(device_ptr);
9859                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9860                         vshader_version_varying_test(device_ptr);
9861                         pshader_version_varying_test(device_ptr);
9862                     } else {
9863                         skip("No vs_3_0 support\n");
9864                     }
9865                 } else {
9866                     skip("No ps_3_0 support\n");
9867                 }
9868             } else {
9869                 skip("No ps_2_0 support\n");
9870             }
9871         }
9872     }
9873     else skip("No ps_1_1 support\n");
9874
9875     texop_test(device_ptr);
9876     texop_range_test(device_ptr);
9877     alphareplicate_test(device_ptr);
9878     dp3_alpha_test(device_ptr);
9879
9880 cleanup:
9881     if(device_ptr) {
9882         ULONG ref;
9883
9884         D3DPRESENT_PARAMETERS present_parameters;
9885         IDirect3DSwapChain9 *swapchain;
9886         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9887         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9888         IDirect3DSwapChain9_Release(swapchain);
9889         ref = IDirect3DDevice9_Release(device_ptr);
9890         DestroyWindow(present_parameters.hDeviceWindow);
9891         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
9892     }
9893 }