wined3d: Implement D3DTA_ALPHAREPLICATE in arbfp and atifs.
[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     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2975     float identity[16] = {1.0, 0.0, 0.0, 0.0,
2976                            0.0, 1.0, 0.0, 0.0,
2977                            0.0, 0.0, 1.0, 0.0,
2978                            0.0, 0.0, 0.0, 1.0};
2979     static const D3DVERTEXELEMENT9 decl_elements[] = {
2980         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2981         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2982         D3DDECL_END()
2983     };
2984     static const D3DVERTEXELEMENT9 decl_elements2[] = {
2985         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2986         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2987         D3DDECL_END()
2988     };
2989     static const D3DVERTEXELEMENT9 decl_elements3[] = {
2990         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2991         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2992         D3DDECL_END()
2993     };
2994     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2995                                                  0x00, 0xff, 0x00, 0x00,
2996                                                  0x00, 0x00, 0x00, 0x00,
2997                                                  0x00, 0x00, 0x00, 0x00};
2998
2999     memset(&lr, 0, sizeof(lr));
3000     memset(&lb, 0, sizeof(lb));
3001     IDirect3DDevice9_GetDirect3D(device, &d3d);
3002     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3003                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3004         fmt = D3DFMT_A16B16G16R16;
3005     }
3006     IDirect3D9_Release(d3d);
3007
3008     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3010     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3011     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3012     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3013     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3014     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3015     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3016     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3017     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3018     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3019     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3020     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3021     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3022     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3023     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3024     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3025     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3026     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3027     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3028     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3029     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3030     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3031     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3032
3033     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3034     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3035     hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3036                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3037     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3038     if(!texture) {
3039         skip("Failed to create the test texture\n");
3040         return;
3041     }
3042
3043     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3044      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3045      * 1.0 in red and green for the x and y coords
3046      */
3047     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3048     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3049     for(y = 0; y < caps.MaxTextureHeight; y++) {
3050         for(x = 0; x < caps.MaxTextureWidth; x++) {
3051             double r_f = (double) y / (double) caps.MaxTextureHeight;
3052             double g_f = (double) x / (double) caps.MaxTextureWidth;
3053             if(fmt == D3DFMT_A16B16G16R16) {
3054                 unsigned short r, g;
3055                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3056                 r = (unsigned short) (r_f * 65536.0);
3057                 g = (unsigned short) (g_f * 65536.0);
3058                 dst[0] = r;
3059                 dst[1] = g;
3060                 dst[2] = 0;
3061                 dst[3] = 65535;
3062             } else {
3063                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3064                 unsigned char r = (unsigned char) (r_f * 255.0);
3065                 unsigned char g = (unsigned char) (g_f * 255.0);
3066                 dst[0] = 0;
3067                 dst[1] = g;
3068                 dst[2] = r;
3069                 dst[3] = 255;
3070             }
3071         }
3072     }
3073     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3074     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3075     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3076     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3077
3078     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3079     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3080     hr = IDirect3DDevice9_BeginScene(device);
3081     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3082     if(SUCCEEDED(hr))
3083     {
3084         float quad1[] = {
3085             -1.0,      -1.0,       0.1,     1.0,    1.0,
3086             -1.0,       0.0,       0.1,     1.0,    1.0,
3087              0.0,      -1.0,       0.1,     1.0,    1.0,
3088              0.0,       0.0,       0.1,     1.0,    1.0,
3089         };
3090         float quad2[] = {
3091             -1.0,       0.0,       0.1,     1.0,    1.0,
3092             -1.0,       1.0,       0.1,     1.0,    1.0,
3093              0.0,       0.0,       0.1,     1.0,    1.0,
3094              0.0,       1.0,       0.1,     1.0,    1.0,
3095         };
3096         float quad3[] = {
3097              0.0,       0.0,       0.1,     0.5,    0.5,
3098              0.0,       1.0,       0.1,     0.5,    0.5,
3099              1.0,       0.0,       0.1,     0.5,    0.5,
3100              1.0,       1.0,       0.1,     0.5,    0.5,
3101         };
3102         float quad4[] = {
3103              320,       480,       0.1,     1.0,    0.0,    1.0,
3104              320,       240,       0.1,     1.0,    0.0,    1.0,
3105              640,       480,       0.1,     1.0,    0.0,    1.0,
3106              640,       240,       0.1,     1.0,    0.0,    1.0,
3107         };
3108         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3109                           0.0, 0.0, 0.0, 0.0,
3110                           0.0, 0.0, 0.0, 0.0,
3111                           0.0, 0.0, 0.0, 0.0};
3112
3113         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3114         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3115         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3116         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3117         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3118
3119         /* What happens with transforms enabled? */
3120         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3121         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3122         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3123         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3124
3125         /* What happens if 4 coords are used, but only 2 given ?*/
3126         mat[8] = 1.0;
3127         mat[13] = 1.0;
3128         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3129         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3130         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3131         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3132         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3133         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3134
3135         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3136          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3137          * due to the coords in the vertices. (turns out red, indeed)
3138          */
3139         memset(mat, 0, sizeof(mat));
3140         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3141         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3142         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3143         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3144         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3145         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3146         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3147         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3148
3149         hr = IDirect3DDevice9_EndScene(device);
3150         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3151     }
3152     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3153     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3154     color = getPixelColor(device, 160, 360);
3155     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3156     color = getPixelColor(device, 160, 120);
3157     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3158     color = getPixelColor(device, 480, 120);
3159     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3160     color = getPixelColor(device, 480, 360);
3161     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3162
3163     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3164     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3165
3166     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3167     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3168     hr = IDirect3DDevice9_BeginScene(device);
3169     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3170     if(SUCCEEDED(hr))
3171     {
3172         float quad1[] = {
3173             -1.0,      -1.0,       0.1,     0.8,    0.2,
3174             -1.0,       0.0,       0.1,     0.8,    0.2,
3175              0.0,      -1.0,       0.1,     0.8,    0.2,
3176              0.0,       0.0,       0.1,     0.8,    0.2,
3177         };
3178         float quad2[] = {
3179             -1.0,       0.0,       0.1,     0.5,    1.0,
3180             -1.0,       1.0,       0.1,     0.5,    1.0,
3181              0.0,       0.0,       0.1,     0.5,    1.0,
3182              0.0,       1.0,       0.1,     0.5,    1.0,
3183         };
3184         float quad3[] = {
3185              0.0,       0.0,       0.1,     0.5,    1.0,
3186              0.0,       1.0,       0.1,     0.5,    1.0,
3187              1.0,       0.0,       0.1,     0.5,    1.0,
3188              1.0,       1.0,       0.1,     0.5,    1.0,
3189         };
3190         float quad4[] = {
3191              0.0,      -1.0,       0.1,     0.8,    0.2,
3192              0.0,       0.0,       0.1,     0.8,    0.2,
3193              1.0,      -1.0,       0.1,     0.8,    0.2,
3194              1.0,       0.0,       0.1,     0.8,    0.2,
3195         };
3196         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3197                           0.0, 0.0, 0.0, 0.0,
3198                           0.0, 1.0, 0.0, 0.0,
3199                           0.0, 0.0, 0.0, 0.0};
3200
3201         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3202          */
3203         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3204         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3205         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3206         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3207
3208         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3209         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3210
3211         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3212          * it behaves like COUNT2 because normal textures require 2 coords
3213          */
3214         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3215         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3216         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3217         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3218
3219         /* Just to be sure, the same as quad2 above */
3220         memset(mat, 0, sizeof(mat));
3221         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3222         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3223         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3224         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3225         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3226         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3227
3228         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3229          * used? And what happens to the first?
3230          */
3231         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3232         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3233         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3234         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3235
3236         hr = IDirect3DDevice9_EndScene(device);
3237         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3238     }
3239     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3241     color = getPixelColor(device, 160, 360);
3242     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3243     color = getPixelColor(device, 160, 120);
3244     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3245     color = getPixelColor(device, 480, 120);
3246     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3247        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3248     color = getPixelColor(device, 480, 360);
3249     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3250        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3251
3252     IDirect3DTexture9_Release(texture);
3253
3254     /* Test projected textures, without any fancy matrices */
3255     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3256     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3257     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3258     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3259     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3260     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3261     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3262     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3263
3264     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3265     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3266     for(x = 0; x < 4; x++) {
3267         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3268     }
3269     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3270     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3271     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3272     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3273
3274     hr = IDirect3DDevice9_BeginScene(device);
3275     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3276     if(SUCCEEDED(hr))
3277     {
3278         const float proj_quads[] = {
3279            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3280             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3281            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3282             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3283            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3284             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3285            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3286             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3287         };
3288
3289         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3290         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3291         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3292         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3293
3294         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3295         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3296         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3297         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3298
3299         hr = IDirect3DDevice9_EndScene(device);
3300         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3301     }
3302
3303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3304     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3305     IDirect3DTexture9_Release(texture);
3306
3307     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3308     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3309     color = getPixelColor(device, 158, 118);
3310     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3311     color = getPixelColor(device, 162, 118);
3312     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3313     color = getPixelColor(device, 158, 122);
3314     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3315     color = getPixelColor(device, 162, 122);
3316     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3317
3318     color = getPixelColor(device, 158, 178);
3319     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3320     color = getPixelColor(device, 162, 178);
3321     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3322     color = getPixelColor(device, 158, 182);
3323     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3324     color = getPixelColor(device, 162, 182);
3325     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3326
3327     color = getPixelColor(device, 318, 118);
3328     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3329     color = getPixelColor(device, 322, 118);
3330     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3331     color = getPixelColor(device, 318, 122);
3332     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3333     color = getPixelColor(device, 322, 122);
3334     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3335
3336     color = getPixelColor(device, 318, 178);
3337     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3338     color = getPixelColor(device, 322, 178);
3339     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3340     color = getPixelColor(device, 318, 182);
3341     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3342     color = getPixelColor(device, 322, 182);
3343     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3344
3345     color = getPixelColor(device, 238, 298);
3346     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3347     color = getPixelColor(device, 242, 298);
3348     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3349     color = getPixelColor(device, 238, 302);
3350     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3351     color = getPixelColor(device, 242, 302);
3352     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3353
3354     color = getPixelColor(device, 238, 388);
3355     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3356     color = getPixelColor(device, 242, 388);
3357     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3358     color = getPixelColor(device, 238, 392);
3359     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3360     color = getPixelColor(device, 242, 392);
3361     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3362
3363     color = getPixelColor(device, 478, 298);
3364     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3365     color = getPixelColor(device, 482, 298);
3366     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3367     color = getPixelColor(device, 478, 302);
3368     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3369     color = getPixelColor(device, 482, 302);
3370     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3371
3372     color = getPixelColor(device, 478, 388);
3373     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3374     color = getPixelColor(device, 482, 388);
3375     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3376     color = getPixelColor(device, 478, 392);
3377     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3378     color = getPixelColor(device, 482, 392);
3379     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3380
3381     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3382     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3383     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3384      * Thus watch out if sampling from texels between 0 and 1.
3385      */
3386     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3387     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3388        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3389     if(!volume) {
3390         skip("Failed to create a volume texture\n");
3391         goto out;
3392     }
3393
3394     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3395     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3396     for(z = 0; z < 32; z++) {
3397         for(y = 0; y < 32; y++) {
3398             for(x = 0; x < 32; x++) {
3399                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3400                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3401                 float r_f = (float) x / 31.0;
3402                 float g_f = (float) y / 31.0;
3403                 float b_f = (float) z / 31.0;
3404
3405                 if(fmt == D3DFMT_A16B16G16R16) {
3406                     unsigned short *mem_s = mem;
3407                     mem_s[0]  = r_f * 65535.0;
3408                     mem_s[1]  = g_f * 65535.0;
3409                     mem_s[2]  = b_f * 65535.0;
3410                     mem_s[3]  = 65535;
3411                 } else {
3412                     unsigned char *mem_c = mem;
3413                     mem_c[0]  = b_f * 255.0;
3414                     mem_c[1]  = g_f * 255.0;
3415                     mem_c[2]  = r_f * 255.0;
3416                     mem_c[3]  = 255;
3417                 }
3418             }
3419         }
3420     }
3421     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3422     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3423
3424     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3425     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3426
3427     hr = IDirect3DDevice9_BeginScene(device);
3428     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3429     if(SUCCEEDED(hr))
3430     {
3431         float quad1[] = {
3432             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3433             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3434              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3435              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3436         };
3437         float quad2[] = {
3438             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3439             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3440              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3441              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3442         };
3443         float quad3[] = {
3444              0.0,       0.0,       0.1,     0.0,    0.0,
3445              0.0,       1.0,       0.1,     0.0,    0.0,
3446              1.0,       0.0,       0.1,     0.0,    0.0,
3447              1.0,       1.0,       0.1,     0.0,    0.0
3448         };
3449         float quad4[] = {
3450              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3451              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3452              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3453              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3454         };
3455         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3456                          0.0, 0.0, 1.0, 0.0,
3457                          0.0, 1.0, 0.0, 0.0,
3458                          0.0, 0.0, 0.0, 1.0};
3459         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3460         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3461
3462         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3463          * values
3464          */
3465         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3466         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3467         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3468         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3469         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3470         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3471
3472         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3473          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3474          * otherwise the w will be missing(blue).
3475          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3476          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3477          */
3478         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3479         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3480         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3481         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3482
3483         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3484         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3485         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3486         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3487         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3488         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3489         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3490         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3491         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3492
3493         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3494          * disable. ATI extends it up to the amount of values needed for the volume texture
3495          */
3496         memset(mat, 0, sizeof(mat));
3497         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3498         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3499         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3500         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3501         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3502         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3503         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3504         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3505
3506         hr = IDirect3DDevice9_EndScene(device);
3507         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3508     }
3509     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3510     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3511
3512     color = getPixelColor(device, 160, 360);
3513     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3514     color = getPixelColor(device, 160, 120);
3515     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3516        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3517     color = getPixelColor(device, 480, 120);
3518     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3519     color = getPixelColor(device, 480, 360);
3520     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3521
3522     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3523     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3524     hr = IDirect3DDevice9_BeginScene(device);
3525     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3526     if(SUCCEEDED(hr))
3527     {
3528         float quad1[] = {
3529             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3530             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3531              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3532              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3533         };
3534         float quad2[] = {
3535             -1.0,       0.0,       0.1,
3536             -1.0,       1.0,       0.1,
3537              0.0,       0.0,       0.1,
3538              0.0,       1.0,       0.1,
3539         };
3540         float quad3[] = {
3541              0.0,       0.0,       0.1,     1.0,
3542              0.0,       1.0,       0.1,     1.0,
3543              1.0,       0.0,       0.1,     1.0,
3544              1.0,       1.0,       0.1,     1.0
3545         };
3546         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3547                            0.0, 0.0, 0.0, 0.0,
3548                            0.0, 0.0, 0.0, 0.0,
3549                            0.0, 1.0, 0.0, 0.0};
3550         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3551                            1.0, 0.0, 0.0, 0.0,
3552                            0.0, 1.0, 0.0, 0.0,
3553                            0.0, 0.0, 1.0, 0.0};
3554         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3555         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3556
3557         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3558          */
3559         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3560         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3561         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3562         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3564         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3565
3566         /* None passed */
3567         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3568         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3569         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3570         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3571         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3572         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3573
3574         /* 4 used, 1 passed */
3575         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3576         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3577         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3578         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3579         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3580         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3581
3582         hr = IDirect3DDevice9_EndScene(device);
3583         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3584     }
3585     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3586     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3587     color = getPixelColor(device, 160, 360);
3588     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3589     color = getPixelColor(device, 160, 120);
3590     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3591     color = getPixelColor(device, 480, 120);
3592     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3593     /* Quad4: unused */
3594
3595     IDirect3DVolumeTexture9_Release(volume);
3596
3597     out:
3598     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3599     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3600     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3601     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3602     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3603     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3604     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3605     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3606     IDirect3DVertexDeclaration9_Release(decl);
3607     IDirect3DVertexDeclaration9_Release(decl2);
3608     IDirect3DVertexDeclaration9_Release(decl3);
3609 }
3610
3611 static void texdepth_test(IDirect3DDevice9 *device)
3612 {
3613     IDirect3DPixelShader9 *shader;
3614     HRESULT hr;
3615     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3616     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3617     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3618     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3619     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3620     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3621     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3622     DWORD shader_code[] = {
3623         0xffff0104,                                                                 /* ps_1_4               */
3624         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3625         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3626         0x0000fffd,                                                                 /* phase                */
3627         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3628         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3629         0x0000ffff                                                                  /* end                  */
3630     };
3631     DWORD color;
3632     float vertex[] = {
3633        -1.0,   -1.0,    0.0,
3634         1.0,   -1.0,    1.0,
3635        -1.0,    1.0,    0.0,
3636         1.0,    1.0,    1.0
3637     };
3638
3639     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3640     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3641
3642     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3644     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3645     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3647     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3648     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3649     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3650     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3651
3652     /* Fill the depth buffer with a gradient */
3653     hr = IDirect3DDevice9_BeginScene(device);
3654     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3655     if(SUCCEEDED(hr))
3656     {
3657         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3658         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3659         hr = IDirect3DDevice9_EndScene(device);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3661     }
3662
3663     /* Now perform the actual tests. Same geometry, but with the shader */
3664     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3665     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3666     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3667     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3668     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3669     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3670
3671     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3672     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3673     hr = IDirect3DDevice9_BeginScene(device);
3674     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3675     if(SUCCEEDED(hr))
3676     {
3677         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3678         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3679
3680         hr = IDirect3DDevice9_EndScene(device);
3681         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3682     }
3683
3684     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3685     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3686     color = getPixelColor(device, 158, 240);
3687     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3688     color = getPixelColor(device, 162, 240);
3689     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3690
3691     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3692
3693     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3694     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3695     hr = IDirect3DDevice9_BeginScene(device);
3696     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3697     if(SUCCEEDED(hr))
3698     {
3699         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3700         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3701
3702         hr = IDirect3DDevice9_EndScene(device);
3703         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3704     }
3705
3706     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3707     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3708     color = getPixelColor(device, 318, 240);
3709     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3710     color = getPixelColor(device, 322, 240);
3711     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3712
3713     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3714
3715     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3717     hr = IDirect3DDevice9_BeginScene(device);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3719     if(SUCCEEDED(hr))
3720     {
3721         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3722         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3723
3724         hr = IDirect3DDevice9_EndScene(device);
3725         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3726     }
3727     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3729
3730     color = getPixelColor(device, 1, 240);
3731     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3732
3733     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3734
3735     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3736     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3737     hr = IDirect3DDevice9_BeginScene(device);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3739     if(SUCCEEDED(hr))
3740     {
3741         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3742         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3743
3744         hr = IDirect3DDevice9_EndScene(device);
3745         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3746     }
3747     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3748     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3749     color = getPixelColor(device, 318, 240);
3750     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3751     color = getPixelColor(device, 322, 240);
3752     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3753
3754     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3755
3756     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3757     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3758     hr = IDirect3DDevice9_BeginScene(device);
3759     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3760     if(SUCCEEDED(hr))
3761     {
3762         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3763         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3764
3765         hr = IDirect3DDevice9_EndScene(device);
3766         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3767     }
3768     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3769     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3770
3771     color = getPixelColor(device, 1, 240);
3772     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3773
3774     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3775
3776     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3777     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3778     hr = IDirect3DDevice9_BeginScene(device);
3779     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3780     if(SUCCEEDED(hr))
3781     {
3782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3783         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3784
3785         hr = IDirect3DDevice9_EndScene(device);
3786         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3787     }
3788     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3789     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3790
3791     color = getPixelColor(device, 638, 240);
3792     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3793
3794     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3795
3796     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3797     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3798     hr = IDirect3DDevice9_BeginScene(device);
3799     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3800     if(SUCCEEDED(hr))
3801     {
3802         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3803         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3804
3805         hr = IDirect3DDevice9_EndScene(device);
3806         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3807     }
3808     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3809     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3810
3811     color = getPixelColor(device, 638, 240);
3812     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3813
3814     /* Cleanup */
3815     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3816     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3817     IDirect3DPixelShader9_Release(shader);
3818
3819     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3820     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3821     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3822     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3823 }
3824
3825 static void texkill_test(IDirect3DDevice9 *device)
3826 {
3827     IDirect3DPixelShader9 *shader;
3828     HRESULT hr;
3829     DWORD color;
3830
3831     const float vertex[] = {
3832     /*                          bottom  top    right    left */
3833         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3834          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3835         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3836          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3837     };
3838
3839     DWORD shader_code_11[] = {
3840     0xffff0101,                                                             /* ps_1_1                     */
3841     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3842     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3843     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3844     0x0000ffff                                                              /* end                        */
3845     };
3846     DWORD shader_code_20[] = {
3847     0xffff0200,                                                             /* ps_2_0                     */
3848     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3849     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3850     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3851     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3852     0x0000ffff                                                              /* end                        */
3853     };
3854
3855     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3856     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3857     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3858     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3859
3860     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3861     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3862     hr = IDirect3DDevice9_BeginScene(device);
3863     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3864     if(SUCCEEDED(hr))
3865     {
3866         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3867         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3868         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3869         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3870         hr = IDirect3DDevice9_EndScene(device);
3871         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3872     }
3873     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3874     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3875     color = getPixelColor(device, 63, 46);
3876     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3877     color = getPixelColor(device, 66, 46);
3878     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3879     color = getPixelColor(device, 63, 49);
3880     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3881     color = getPixelColor(device, 66, 49);
3882     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3883
3884     color = getPixelColor(device, 578, 46);
3885     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3886     color = getPixelColor(device, 575, 46);
3887     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3888     color = getPixelColor(device, 578, 49);
3889     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3890     color = getPixelColor(device, 575, 49);
3891     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3892
3893     color = getPixelColor(device, 63, 430);
3894     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3895     color = getPixelColor(device, 63, 433);
3896     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3897     color = getPixelColor(device, 66, 433);
3898     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3899     color = getPixelColor(device, 66, 430);
3900     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3901
3902     color = getPixelColor(device, 578, 430);
3903     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3904     color = getPixelColor(device, 578, 433);
3905     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3906     color = getPixelColor(device, 575, 433);
3907     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3908     color = getPixelColor(device, 575, 430);
3909     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3910
3911     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3912     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3913     IDirect3DPixelShader9_Release(shader);
3914
3915     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3916     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3917     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3918     if(FAILED(hr)) {
3919         skip("Failed to create 2.0 test shader, most likely not supported\n");
3920         return;
3921     }
3922
3923     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3924     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3925     hr = IDirect3DDevice9_BeginScene(device);
3926     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3927     if(SUCCEEDED(hr))
3928     {
3929         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3930         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3931         hr = IDirect3DDevice9_EndScene(device);
3932         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3933     }
3934     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3935
3936     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3937     color = getPixelColor(device, 63, 46);
3938     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3939     color = getPixelColor(device, 66, 46);
3940     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3941     color = getPixelColor(device, 63, 49);
3942     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3943     color = getPixelColor(device, 66, 49);
3944     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3945
3946     color = getPixelColor(device, 578, 46);
3947     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3948     color = getPixelColor(device, 575, 46);
3949     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3950     color = getPixelColor(device, 578, 49);
3951     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3952     color = getPixelColor(device, 575, 49);
3953     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3954
3955     color = getPixelColor(device, 63, 430);
3956     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3957     color = getPixelColor(device, 63, 433);
3958     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3959     color = getPixelColor(device, 66, 433);
3960     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3961     color = getPixelColor(device, 66, 430);
3962     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3963
3964     color = getPixelColor(device, 578, 430);
3965     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3966     color = getPixelColor(device, 578, 433);
3967     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3968     color = getPixelColor(device, 575, 433);
3969     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3970     color = getPixelColor(device, 575, 430);
3971     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3972
3973     /* Cleanup */
3974     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3975     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3976     IDirect3DPixelShader9_Release(shader);
3977 }
3978
3979 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3980 {
3981     IDirect3D9 *d3d9;
3982     HRESULT hr;
3983     IDirect3DTexture9 *texture;
3984     IDirect3DPixelShader9 *shader;
3985     IDirect3DPixelShader9 *shader2;
3986     D3DLOCKED_RECT lr;
3987     DWORD color;
3988     DWORD shader_code[] = {
3989         0xffff0101,                             /* ps_1_1       */
3990         0x00000042, 0xb00f0000,                 /* tex t0       */
3991         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
3992         0x0000ffff                              /* end          */
3993     };
3994     DWORD shader_code2[] = {
3995         0xffff0101,                             /* ps_1_1       */
3996         0x00000042, 0xb00f0000,                 /* tex t0       */
3997         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
3998         0x0000ffff                              /* end          */
3999     };
4000
4001     float quad[] = {
4002        -1.0,   -1.0,   0.1,     0.5,    0.5,
4003         1.0,   -1.0,   0.1,     0.5,    0.5,
4004        -1.0,    1.0,   0.1,     0.5,    0.5,
4005         1.0,    1.0,   0.1,     0.5,    0.5,
4006     };
4007
4008     memset(&lr, 0, sizeof(lr));
4009     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4010     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4011                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4012     IDirect3D9_Release(d3d9);
4013     if(FAILED(hr)) {
4014         skip("No D3DFMT_X8L8V8U8 support\n");
4015     };
4016
4017     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4018     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4019
4020     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4022     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4023     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4024     *((DWORD *) lr.pBits) = 0x11ca3141;
4025     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4026     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4027
4028     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4030     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4031     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4032
4033     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4034     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4035     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4036     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4037     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4038     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4039
4040     hr = IDirect3DDevice9_BeginScene(device);
4041     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4042     if(SUCCEEDED(hr))
4043     {
4044         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4045         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4046
4047         hr = IDirect3DDevice9_EndScene(device);
4048         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4049     }
4050     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4051     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4052     color = getPixelColor(device, 578, 430);
4053     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4054        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4055
4056     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4057     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4058     hr = IDirect3DDevice9_BeginScene(device);
4059     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4060     if(SUCCEEDED(hr))
4061     {
4062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4063         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4064
4065         hr = IDirect3DDevice9_EndScene(device);
4066         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4067     }
4068     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4069     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4070     color = getPixelColor(device, 578, 430);
4071     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4072
4073     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4074     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4075     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4076     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4077     IDirect3DPixelShader9_Release(shader);
4078     IDirect3DPixelShader9_Release(shader2);
4079     IDirect3DTexture9_Release(texture);
4080 }
4081
4082 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4083 {
4084     HRESULT hr;
4085     IDirect3D9 *d3d;
4086     IDirect3DTexture9 *texture = NULL;
4087     IDirect3DSurface9 *surface;
4088     DWORD color;
4089     const RECT r1 = {256, 256, 512, 512};
4090     const RECT r2 = {512, 256, 768, 512};
4091     const RECT r3 = {256, 512, 512, 768};
4092     const RECT r4 = {512, 512, 768, 768};
4093     unsigned int x, y;
4094     D3DLOCKED_RECT lr;
4095     memset(&lr, 0, sizeof(lr));
4096
4097     IDirect3DDevice9_GetDirect3D(device, &d3d);
4098     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4099        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4100         skip("No autogenmipmap support\n");
4101         IDirect3D9_Release(d3d);
4102         return;
4103     }
4104     IDirect3D9_Release(d3d);
4105
4106     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4107     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4108
4109     /* Make the mipmap big, so that a smaller mipmap is used
4110      */
4111     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4112                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4113     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4114
4115     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4116     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4117     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4118     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4119     for(y = 0; y < 1024; y++) {
4120         for(x = 0; x < 1024; x++) {
4121             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4122             POINT pt;
4123
4124             pt.x = x;
4125             pt.y = y;
4126             if(PtInRect(&r1, pt)) {
4127                 *dst = 0xffff0000;
4128             } else if(PtInRect(&r2, pt)) {
4129                 *dst = 0xff00ff00;
4130             } else if(PtInRect(&r3, pt)) {
4131                 *dst = 0xff0000ff;
4132             } else if(PtInRect(&r4, pt)) {
4133                 *dst = 0xff000000;
4134             } else {
4135                 *dst = 0xffffffff;
4136             }
4137         }
4138     }
4139     hr = IDirect3DSurface9_UnlockRect(surface);
4140     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4141     IDirect3DSurface9_Release(surface);
4142
4143     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4145     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4147
4148     hr = IDirect3DDevice9_BeginScene(device);
4149     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4150     if(SUCCEEDED(hr)) {
4151         const float quad[] =  {
4152            -0.5,   -0.5,    0.1,    0.0,    0.0,
4153            -0.5,    0.5,    0.1,    0.0,    1.0,
4154             0.5,   -0.5,    0.1,    1.0,    0.0,
4155             0.5,    0.5,    0.1,    1.0,    1.0
4156         };
4157
4158         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4159         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4160         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4161         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4162         hr = IDirect3DDevice9_EndScene(device);
4163         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4164     }
4165     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4166     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4167     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4168     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4169     IDirect3DTexture9_Release(texture);
4170
4171     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4172     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4173     color = getPixelColor(device, 200, 200);
4174     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4175     color = getPixelColor(device, 280, 200);
4176     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4177     color = getPixelColor(device, 360, 200);
4178     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4179     color = getPixelColor(device, 440, 200);
4180     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4181     color = getPixelColor(device, 200, 270);
4182     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4183     color = getPixelColor(device, 280, 270);
4184     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4185     color = getPixelColor(device, 360, 270);
4186     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4187     color = getPixelColor(device, 440, 270);
4188     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4189 }
4190
4191 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4192 {
4193     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4194     IDirect3DVertexDeclaration9 *decl;
4195     HRESULT hr;
4196     DWORD color;
4197     DWORD shader_code_11[] =  {
4198         0xfffe0101,                                         /* vs_1_1           */
4199         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4200         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4201         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4202         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4203         0x0000ffff                                          /* end              */
4204     };
4205     DWORD shader_code_11_2[] =  {
4206         0xfffe0101,                                         /* vs_1_1           */
4207         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4208         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4209         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4210         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4211         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4212         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4213         0x0000ffff                                          /* end              */
4214     };
4215     DWORD shader_code_20[] =  {
4216         0xfffe0200,                                         /* vs_2_0           */
4217         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4218         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4219         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4220         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4221         0x0000ffff                                          /* end              */
4222     };
4223     DWORD shader_code_20_2[] =  {
4224         0xfffe0200,                                         /* vs_2_0           */
4225         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4226         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4227         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4228         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4229         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4230         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4231         0x0000ffff                                          /* end              */
4232     };
4233     static const D3DVERTEXELEMENT9 decl_elements[] = {
4234         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4235         D3DDECL_END()
4236     };
4237     float quad1[] = {
4238         -1.0,   -1.0,   0.1,
4239          0.0,   -1.0,   0.1,
4240         -1.0,    0.0,   0.1,
4241          0.0,    0.0,   0.1
4242     };
4243     float quad2[] = {
4244          0.0,   -1.0,   0.1,
4245          1.0,   -1.0,   0.1,
4246          0.0,    0.0,   0.1,
4247          1.0,    0.0,   0.1
4248     };
4249     float quad3[] = {
4250          0.0,    0.0,   0.1,
4251          1.0,    0.0,   0.1,
4252          0.0,    1.0,   0.1,
4253          1.0,    1.0,   0.1
4254     };
4255     float quad4[] = {
4256         -1.0,    0.0,   0.1,
4257          0.0,    0.0,   0.1,
4258         -1.0,    1.0,   0.1,
4259          0.0,    1.0,   0.1
4260     };
4261     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4262     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4263
4264     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4265     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4266
4267     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4268     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4269     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4270     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4271     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4272     if(FAILED(hr)) shader_20 = NULL;
4273     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4274     if(FAILED(hr)) shader_20_2 = NULL;
4275     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4276     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4277
4278     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4279     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4280     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4281     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4282     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4283     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4284
4285     hr = IDirect3DDevice9_BeginScene(device);
4286     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4287     if(SUCCEEDED(hr))
4288     {
4289         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4290         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4291         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4292         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4293
4294         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4295         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4296         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4297         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4298
4299         if(shader_20) {
4300             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4301             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4302             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4303             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4304         }
4305
4306         if(shader_20_2) {
4307             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4308             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4309             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4310             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4311         }
4312
4313         hr = IDirect3DDevice9_EndScene(device);
4314         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4315     }
4316     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4317     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4318
4319     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4320     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4321     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4322     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4323
4324     color = getPixelColor(device, 160, 360);
4325     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4326        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4327     color = getPixelColor(device, 480, 360);
4328     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4330     if(shader_20) {
4331         color = getPixelColor(device, 160, 120);
4332         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4333            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4334     }
4335     if(shader_20_2) {
4336         color = getPixelColor(device, 480, 120);
4337         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4338            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4339     }
4340
4341     IDirect3DVertexDeclaration9_Release(decl);
4342     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4343     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4344     IDirect3DVertexShader9_Release(shader_11_2);
4345     IDirect3DVertexShader9_Release(shader_11);
4346 }
4347
4348 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4349 {
4350     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4351     HRESULT hr;
4352     DWORD color;
4353     DWORD shader_code_11[] =  {
4354         0xffff0101,                                         /* ps_1_1           */
4355         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4356         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4357         0x0000ffff                                          /* end              */
4358     };
4359     DWORD shader_code_12[] =  {
4360         0xffff0102,                                         /* ps_1_2           */
4361         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4362         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4363         0x0000ffff                                          /* end              */
4364     };
4365     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4366      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4367      * During development of this test, 1.3 shaders were verified too
4368      */
4369     DWORD shader_code_14[] =  {
4370         0xffff0104,                                         /* ps_1_4           */
4371         /* Try to make one constant local. It gets clamped too, although the binary contains
4372          * the bigger numbers
4373          */
4374         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4375         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4376         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4377         0x0000ffff                                          /* end              */
4378     };
4379     DWORD shader_code_20[] =  {
4380         0xffff0200,                                         /* ps_2_0           */
4381         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4382         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4383         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4384         0x0000ffff                                          /* end              */
4385     };
4386     float quad1[] = {
4387         -1.0,   -1.0,   0.1,
4388          0.0,   -1.0,   0.1,
4389         -1.0,    0.0,   0.1,
4390          0.0,    0.0,   0.1
4391     };
4392     float quad2[] = {
4393          0.0,   -1.0,   0.1,
4394          1.0,   -1.0,   0.1,
4395          0.0,    0.0,   0.1,
4396          1.0,    0.0,   0.1
4397     };
4398     float quad3[] = {
4399          0.0,    0.0,   0.1,
4400          1.0,    0.0,   0.1,
4401          0.0,    1.0,   0.1,
4402          1.0,    1.0,   0.1
4403     };
4404     float quad4[] = {
4405         -1.0,    0.0,   0.1,
4406          0.0,    0.0,   0.1,
4407         -1.0,    1.0,   0.1,
4408          0.0,    1.0,   0.1
4409     };
4410     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4411     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4412
4413     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4414     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4415
4416     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4417     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4418     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4419     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4420     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4421     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4422     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4423     if(FAILED(hr)) shader_20 = NULL;
4424
4425     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4426     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4427     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4428     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4429     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4430     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4431
4432     hr = IDirect3DDevice9_BeginScene(device);
4433     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4434     if(SUCCEEDED(hr))
4435     {
4436         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4437         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4438         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4439         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4440
4441         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4442         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4443         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4444         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4445
4446         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4447         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4448         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4449         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4450
4451         if(shader_20) {
4452             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4453             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4454             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4455             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4456         }
4457
4458         hr = IDirect3DDevice9_EndScene(device);
4459         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4460     }
4461     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4462     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4463
4464     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4465     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4466
4467     color = getPixelColor(device, 160, 360);
4468     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4469        "quad 1 has color %08x, expected 0x00808000\n", color);
4470     color = getPixelColor(device, 480, 360);
4471     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4472        "quad 2 has color %08x, expected 0x00808000\n", color);
4473     color = getPixelColor(device, 480, 120);
4474     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4475        "quad 3 has color %08x, expected 0x00808000\n", color);
4476     if(shader_20) {
4477         color = getPixelColor(device, 160, 120);
4478         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4479            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4480     }
4481
4482     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4483     IDirect3DPixelShader9_Release(shader_14);
4484     IDirect3DPixelShader9_Release(shader_12);
4485     IDirect3DPixelShader9_Release(shader_11);
4486 }
4487
4488 static void dp2add_ps_test(IDirect3DDevice9 *device)
4489 {
4490     IDirect3DPixelShader9 *shader_dp2add = NULL;
4491     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4492     HRESULT hr;
4493     DWORD color;
4494
4495     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4496      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4497      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4498      * r0 first.
4499      * The result here for the r,g,b components should be roughly 0.5:
4500      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4501     static const DWORD shader_code_dp2add[] =  {
4502         0xffff0200,                                                             /* ps_2_0                       */
4503         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4504
4505         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4506         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4507
4508         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4509         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4510         0x0000ffff                                                              /* end                          */
4511     };
4512
4513     /* Test the _sat modifier, too.  Result here should be:
4514      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4515      *      _SAT: ==> 1.0
4516      *   ADD: (1.0 + -0.5) = 0.5
4517      */
4518     static const DWORD shader_code_dp2add_sat[] =  {
4519         0xffff0200,                                                             /* ps_2_0                           */
4520         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4521
4522         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4523         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4524         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4525
4526         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4527         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4528         0x0000ffff                                                              /* end                              */
4529     };
4530
4531     const float quad[] = {
4532         -1.0,   -1.0,   0.1,
4533          1.0,   -1.0,   0.1,
4534         -1.0,    1.0,   0.1,
4535          1.0,    1.0,   0.1
4536     };
4537
4538
4539     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4541
4542     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4543     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4544
4545     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4546     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4547
4548     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4549     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4550
4551     if (shader_dp2add) {
4552
4553         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4554         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4555
4556         hr = IDirect3DDevice9_BeginScene(device);
4557         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4558         if(SUCCEEDED(hr))
4559         {
4560             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4561             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4562
4563             hr = IDirect3DDevice9_EndScene(device);
4564             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4565         }
4566         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4567         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4568
4569         color = getPixelColor(device, 360, 240);
4570         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4571
4572         IDirect3DPixelShader9_Release(shader_dp2add);
4573     } else {
4574         skip("dp2add shader creation failed\n");
4575     }
4576
4577     if (shader_dp2add_sat) {
4578
4579         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4580         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4581
4582         hr = IDirect3DDevice9_BeginScene(device);
4583         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4584         if(SUCCEEDED(hr))
4585         {
4586             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4587             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4588
4589             hr = IDirect3DDevice9_EndScene(device);
4590             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4591         }
4592         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4593         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4594
4595         color = getPixelColor(device, 360, 240);
4596         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4597
4598         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4599     } else {
4600         skip("dp2add shader creation failed\n");
4601     }
4602
4603     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4604     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4605 }
4606
4607 static void cnd_test(IDirect3DDevice9 *device)
4608 {
4609     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4610     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4611     HRESULT hr;
4612     DWORD color;
4613     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4614      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4615      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4616      */
4617     DWORD shader_code_11[] =  {
4618         0xffff0101,                                                                 /* ps_1_1               */
4619         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4620         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4621         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4622         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4623         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4624         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4625         0x0000ffff                                                                  /* end                  */
4626     };
4627     DWORD shader_code_12[] =  {
4628         0xffff0102,                                                                 /* ps_1_2               */
4629         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4630         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4631         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4632         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4633         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4634         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4635         0x0000ffff                                                                  /* end                  */
4636     };
4637     DWORD shader_code_13[] =  {
4638         0xffff0103,                                                                 /* ps_1_3               */
4639         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4640         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4641         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4642         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4643         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4644         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4645         0x0000ffff                                                                  /* end                  */
4646     };
4647     DWORD shader_code_14[] =  {
4648         0xffff0104,                                                                 /* ps_1_3               */
4649         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4650         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4651         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4652         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4653         0x0000ffff                                                                  /* end                  */
4654     };
4655
4656     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4657      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4658      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4659      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4660      * native CreatePixelShader returns an error.
4661      *
4662      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4663      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4664      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4665      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4666      */
4667     DWORD shader_code_11_coissue[] =  {
4668         0xffff0101,                                                             /* ps_1_1                   */
4669         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4670         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4671         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4672         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4673         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4674         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4675         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4676         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4677         /* 0x40000000 = D3DSI_COISSUE */
4678         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4679         0x0000ffff                                                              /* end                      */
4680     };
4681     DWORD shader_code_12_coissue[] =  {
4682         0xffff0102,                                                             /* ps_1_2                   */
4683         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4684         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4685         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4686         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4687         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4688         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4689         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4690         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4691         /* 0x40000000 = D3DSI_COISSUE */
4692         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4693         0x0000ffff                                                              /* end                      */
4694     };
4695     DWORD shader_code_13_coissue[] =  {
4696         0xffff0103,                                                             /* ps_1_3                   */
4697         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4698         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4699         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4700         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4701         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4702         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4703         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4704         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4705         /* 0x40000000 = D3DSI_COISSUE */
4706         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4707         0x0000ffff                                                              /* end                      */
4708     };
4709     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4710      * compare against 0.5
4711      */
4712     DWORD shader_code_14_coissue[] =  {
4713         0xffff0104,                                                             /* ps_1_4                   */
4714         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4715         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4716         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4717         /* 0x40000000 = D3DSI_COISSUE */
4718         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4719         0x0000ffff                                                              /* end                      */
4720     };
4721     float quad1[] = {
4722         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4723          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4724         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4725          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4726     };
4727     float quad2[] = {
4728          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4729          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4730          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4731          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4732     };
4733     float quad3[] = {
4734          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4735          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4736          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4737          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4738     };
4739     float quad4[] = {
4740         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4741          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4742         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4743          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4744     };
4745     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4746     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4747     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4748     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4749
4750     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4752
4753     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4754     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4755     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4756     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4757     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4758     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4759     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4760     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4761     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4762     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4763     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4764     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4765     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4767     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4768     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4769
4770     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4771     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4772     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4773     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4774     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4775     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4776
4777     hr = IDirect3DDevice9_BeginScene(device);
4778     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4779     if(SUCCEEDED(hr))
4780     {
4781         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4782         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4783         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4784         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4785
4786         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4787         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4788         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4789         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4790
4791         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4792         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4794         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4795
4796         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4797         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4798         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4799         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4800
4801         hr = IDirect3DDevice9_EndScene(device);
4802         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4803     }
4804     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4805     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4806
4807     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4808     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4809
4810     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4811     color = getPixelColor(device, 158, 118);
4812     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4813     color = getPixelColor(device, 162, 118);
4814     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4815     color = getPixelColor(device, 158, 122);
4816     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4817     color = getPixelColor(device, 162, 122);
4818     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4819
4820     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4821     color = getPixelColor(device, 158, 358);
4822     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4823     color = getPixelColor(device, 162, 358);
4824     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4825         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4826     color = getPixelColor(device, 158, 362);
4827     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4828     color = getPixelColor(device, 162, 362);
4829     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4830         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4831
4832     /* 1.2 shader */
4833     color = getPixelColor(device, 478, 358);
4834     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4835     color = getPixelColor(device, 482, 358);
4836     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4837         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4838     color = getPixelColor(device, 478, 362);
4839     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4840     color = getPixelColor(device, 482, 362);
4841     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4842         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4843
4844     /* 1.3 shader */
4845     color = getPixelColor(device, 478, 118);
4846     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4847     color = getPixelColor(device, 482, 118);
4848     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4849         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4850     color = getPixelColor(device, 478, 122);
4851     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4852     color = getPixelColor(device, 482, 122);
4853     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4854         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4855
4856     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4857     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4858     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4859     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4860     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4861     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4862
4863     hr = IDirect3DDevice9_BeginScene(device);
4864     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4865     if(SUCCEEDED(hr))
4866     {
4867         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4868         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4869         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4870         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4871
4872         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4873         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4874         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4875         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4876
4877         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4878         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4879         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4880         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4881
4882         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4883         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4885         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4886
4887         hr = IDirect3DDevice9_EndScene(device);
4888         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4889     }
4890     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4891     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4892
4893     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4894     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4895
4896     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4897      * that we swapped the values in c1 and c2 to make the other tests return some color
4898      */
4899     color = getPixelColor(device, 158, 118);
4900     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4901     color = getPixelColor(device, 162, 118);
4902     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4903     color = getPixelColor(device, 158, 122);
4904     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4905     color = getPixelColor(device, 162, 122);
4906     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4907
4908     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4909     color = getPixelColor(device, 158, 358);
4910     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4911         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4912     color = getPixelColor(device, 162, 358);
4913     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4914         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4915     color = getPixelColor(device, 158, 362);
4916     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4917         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4918     color = getPixelColor(device, 162, 362);
4919     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4920         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4921
4922     /* 1.2 shader */
4923     color = getPixelColor(device, 478, 358);
4924     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4925         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4926     color = getPixelColor(device, 482, 358);
4927     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4928         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4929     color = getPixelColor(device, 478, 362);
4930     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4931         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4932     color = getPixelColor(device, 482, 362);
4933     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4934         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4935
4936     /* 1.3 shader */
4937     color = getPixelColor(device, 478, 118);
4938     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4939         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4940     color = getPixelColor(device, 482, 118);
4941     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4942         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4943     color = getPixelColor(device, 478, 122);
4944     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4945         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4946     color = getPixelColor(device, 482, 122);
4947     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4948         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4949
4950     IDirect3DPixelShader9_Release(shader_14_coissue);
4951     IDirect3DPixelShader9_Release(shader_13_coissue);
4952     IDirect3DPixelShader9_Release(shader_12_coissue);
4953     IDirect3DPixelShader9_Release(shader_11_coissue);
4954     IDirect3DPixelShader9_Release(shader_14);
4955     IDirect3DPixelShader9_Release(shader_13);
4956     IDirect3DPixelShader9_Release(shader_12);
4957     IDirect3DPixelShader9_Release(shader_11);
4958 }
4959
4960 static void nested_loop_test(IDirect3DDevice9 *device) {
4961     const DWORD shader_code[] = {
4962         0xffff0300,                                                             /* ps_3_0               */
4963         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
4964         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4965         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
4966         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
4967         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4968         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
4969         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
4970         0x0000001d,                                                             /* endloop              */
4971         0x0000001d,                                                             /* endloop              */
4972         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
4973         0x0000ffff                                                              /* end                  */
4974     };
4975     IDirect3DPixelShader9 *shader;
4976     HRESULT hr;
4977     DWORD color;
4978     const float quad[] = {
4979         -1.0,   -1.0,   0.1,
4980          1.0,   -1.0,   0.1,
4981         -1.0,    1.0,   0.1,
4982          1.0,    1.0,   0.1
4983     };
4984
4985     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4986     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
4987     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4988     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
4989     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4990     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4991     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4992     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4993
4994     hr = IDirect3DDevice9_BeginScene(device);
4995     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4996     if(SUCCEEDED(hr))
4997     {
4998         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4999         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5000         hr = IDirect3DDevice9_EndScene(device);
5001         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5002     }
5003     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5004     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5005
5006     color = getPixelColor(device, 360, 240);
5007     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5008        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5009
5010     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5011     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5012     IDirect3DPixelShader9_Release(shader);
5013 }
5014
5015 struct varying_test_struct
5016 {
5017     const DWORD             *shader_code;
5018     IDirect3DPixelShader9   *shader;
5019     DWORD                   color, color_rhw;
5020     const char              *name;
5021     BOOL                    todo, todo_rhw;
5022 };
5023
5024 struct hugeVertex
5025 {
5026     float pos_x,        pos_y,      pos_z,      rhw;
5027     float weight_1,     weight_2,   weight_3,   weight_4;
5028     float index_1,      index_2,    index_3,    index_4;
5029     float normal_1,     normal_2,   normal_3,   normal_4;
5030     float fog_1,        fog_2,      fog_3,      fog_4;
5031     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5032     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5033     float binormal_1,   binormal_2, binormal_3, binormal_4;
5034     float depth_1,      depth_2,    depth_3,    depth_4;
5035     DWORD diffuse, specular;
5036 };
5037
5038 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5039     /* dcl_position: fails to compile */
5040     const DWORD blendweight_code[] = {
5041         0xffff0300,                             /* ps_3_0                   */
5042         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5043         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5044         0x0000ffff                              /* end                      */
5045     };
5046     const DWORD blendindices_code[] = {
5047         0xffff0300,                             /* ps_3_0                   */
5048         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5049         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5050         0x0000ffff                              /* end                      */
5051     };
5052     const DWORD normal_code[] = {
5053         0xffff0300,                             /* ps_3_0                   */
5054         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5055         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5056         0x0000ffff                              /* end                      */
5057     };
5058     /* psize: fails? */
5059     const DWORD texcoord0_code[] = {
5060         0xffff0300,                             /* ps_3_0                   */
5061         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5062         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5063         0x0000ffff                              /* end                      */
5064     };
5065     const DWORD tangent_code[] = {
5066         0xffff0300,                             /* ps_3_0                   */
5067         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5068         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5069         0x0000ffff                              /* end                      */
5070     };
5071     const DWORD binormal_code[] = {
5072         0xffff0300,                             /* ps_3_0                   */
5073         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5074         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5075         0x0000ffff                              /* end                      */
5076     };
5077     /* tessfactor: fails */
5078     /* positiont: fails */
5079     const DWORD color_code[] = {
5080         0xffff0300,                             /* ps_3_0                   */
5081         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5082         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5083         0x0000ffff                              /* end                      */
5084     };
5085     const DWORD fog_code[] = {
5086         0xffff0300,                             /* ps_3_0                   */
5087         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5088         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5089         0x0000ffff                              /* end                      */
5090     };
5091     const DWORD depth_code[] = {
5092         0xffff0300,                             /* ps_3_0                   */
5093         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5094         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5095         0x0000ffff                              /* end                      */
5096     };
5097     const DWORD specular_code[] = {
5098         0xffff0300,                             /* ps_3_0                   */
5099         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5100         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5101         0x0000ffff                              /* end                      */
5102     };
5103     /* sample: fails */
5104
5105     struct varying_test_struct tests[] = {
5106        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5107        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5108        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5109        /* Why does dx not forward the texcoord? */
5110        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5111        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5112        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5113        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5114        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5115        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5116        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5117     };
5118     /* Declare a monster vertex type :-) */
5119     static const D3DVERTEXELEMENT9 decl_elements[] = {
5120         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5121         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5122         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5123         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5124         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5125         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5126         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5127         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5128         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5129         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5130         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5131         D3DDECL_END()
5132     };
5133     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5134         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5135         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5136         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5137         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5138         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5139         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5140         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5141         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5142         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5143         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5144         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5145         D3DDECL_END()
5146     };
5147     struct hugeVertex data[4] = {
5148         {
5149             -1.0,   -1.0,   0.1,    1.0,
5150              0.1,    0.1,   0.1,    0.1,
5151              0.2,    0.2,   0.2,    0.2,
5152              0.3,    0.3,   0.3,    0.3,
5153              0.4,    0.4,   0.4,    0.4,
5154              0.50,   0.55,  0.55,   0.55,
5155              0.6,    0.6,   0.6,    0.7,
5156              0.7,    0.7,   0.7,    0.6,
5157              0.8,    0.8,   0.8,    0.8,
5158              0xe6e6e6e6, /* 0.9 * 256 */
5159              0x224488ff  /* Nothing special */
5160         },
5161         {
5162              1.0,   -1.0,   0.1,    1.0,
5163              0.1,    0.1,   0.1,    0.1,
5164              0.2,    0.2,   0.2,    0.2,
5165              0.3,    0.3,   0.3,    0.3,
5166              0.4,    0.4,   0.4,    0.4,
5167              0.50,   0.55,  0.55,   0.55,
5168              0.6,    0.6,   0.6,    0.7,
5169              0.7,    0.7,   0.7,    0.6,
5170              0.8,    0.8,   0.8,    0.8,
5171              0xe6e6e6e6, /* 0.9 * 256 */
5172              0x224488ff /* Nothing special */
5173         },
5174         {
5175             -1.0,    1.0,   0.1,    1.0,
5176              0.1,    0.1,   0.1,    0.1,
5177              0.2,    0.2,   0.2,    0.2,
5178              0.3,    0.3,   0.3,    0.3,
5179              0.4,    0.4,   0.4,    0.4,
5180              0.50,   0.55,  0.55,   0.55,
5181              0.6,    0.6,   0.6,    0.7,
5182              0.7,    0.7,   0.7,    0.6,
5183              0.8,    0.8,   0.8,    0.8,
5184              0xe6e6e6e6, /* 0.9 * 256 */
5185              0x224488ff /* Nothing special */
5186         },
5187         {
5188              1.0,    1.0,   0.1,    1.0,
5189              0.1,    0.1,   0.1,    0.1,
5190              0.2,    0.2,   0.2,    0.2,
5191              0.3,    0.3,   0.3,    0.3,
5192              0.4,    0.4,   0.4,    0.4,
5193              0.50,   0.55,  0.55,   0.55,
5194              0.6,    0.6,   0.6,    0.7,
5195              0.7,    0.7,   0.7,    0.6,
5196              0.8,    0.8,   0.8,    0.8,
5197              0xe6e6e6e6, /* 0.9 * 256 */
5198              0x224488ff /* Nothing special */
5199         },
5200     };
5201     struct hugeVertex data2[4];
5202     IDirect3DVertexDeclaration9 *decl;
5203     IDirect3DVertexDeclaration9 *decl2;
5204     HRESULT hr;
5205     unsigned int i;
5206     DWORD color, r, g, b, r_e, g_e, b_e;
5207     BOOL drawok;
5208
5209     memcpy(data2, data, sizeof(data2));
5210     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5211     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5212     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5213     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5214
5215     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5216     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5217     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5218     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5219     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5220     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5221
5222     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5223     {
5224         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5225         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5226            tests[i].name, hr);
5227     }
5228
5229     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5230     {
5231         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5232         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5233
5234         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5235         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5236
5237         hr = IDirect3DDevice9_BeginScene(device);
5238         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5239         drawok = FALSE;
5240         if(SUCCEEDED(hr))
5241         {
5242             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5243             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5244             drawok = SUCCEEDED(hr);
5245             hr = IDirect3DDevice9_EndScene(device);
5246             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5247         }
5248         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5249         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5250
5251         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5252          * the failure and do not check the color if it failed
5253          */
5254         if(!drawok) {
5255             continue;
5256         }
5257
5258         color = getPixelColor(device, 360, 240);
5259         r = color & 0x00ff0000 >> 16;
5260         g = color & 0x0000ff00 >>  8;
5261         b = color & 0x000000ff;
5262         r_e = tests[i].color & 0x00ff0000 >> 16;
5263         g_e = tests[i].color & 0x0000ff00 >>  8;
5264         b_e = tests[i].color & 0x000000ff;
5265
5266         if(tests[i].todo) {
5267             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5268                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5269                          tests[i].name, color, tests[i].color);
5270         } else {
5271             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5272                "Test %s returned color 0x%08x, expected 0x%08x\n",
5273                tests[i].name, color, tests[i].color);
5274         }
5275     }
5276
5277     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5278     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5279     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5280     {
5281         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5282         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5283
5284         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5285         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5286
5287         hr = IDirect3DDevice9_BeginScene(device);
5288         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5289         if(SUCCEEDED(hr))
5290         {
5291             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5292             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5293             hr = IDirect3DDevice9_EndScene(device);
5294             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5295         }
5296         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5297         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5298
5299         color = getPixelColor(device, 360, 240);
5300         r = color & 0x00ff0000 >> 16;
5301         g = color & 0x0000ff00 >>  8;
5302         b = color & 0x000000ff;
5303         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5304         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5305         b_e = tests[i].color_rhw & 0x000000ff;
5306
5307         if(tests[i].todo_rhw) {
5308             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5309              * pipeline
5310              */
5311             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5312                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5313                          tests[i].name, color, tests[i].color_rhw);
5314         } else {
5315             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5316                "Test %s returned color 0x%08x, expected 0x%08x\n",
5317                tests[i].name, color, tests[i].color_rhw);
5318         }
5319     }
5320
5321     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5322     {
5323         IDirect3DPixelShader9_Release(tests[i].shader);
5324     }
5325
5326     IDirect3DVertexDeclaration9_Release(decl2);
5327     IDirect3DVertexDeclaration9_Release(decl);
5328 }
5329
5330 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5331     static const DWORD ps_code[] = {
5332     0xffff0300,                                                             /* ps_3_0                       */
5333     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5334     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5335     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5336     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5337     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5338     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5339     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5340     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5341     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5342
5343     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5344     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5345     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5346     0x0000001d,                                                             /* endloop                      */
5347     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5348     0x0000ffff                                                              /* end                          */
5349     };
5350     static const DWORD vs_1_code[] = {
5351     0xfffe0101,                                                             /* vs_1_1                       */
5352     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5353     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5354     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5355     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5356     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5357     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5358     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5359     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5360     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5361     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5362     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5363     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5364     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5365     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5366     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5367     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5368     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5369     0x0000ffff
5370     };
5371     DWORD vs_2_code[] = {
5372     0xfffe0200,                                                             /* vs_2_0                       */
5373     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5374     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5375     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5376     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5377     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5378     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5379     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5380     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5381     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5382     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5383     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5384     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5385     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5386     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5387     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5388     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5389     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5390     0x0000ffff                                                              /* end                          */
5391     };
5392     /* TODO: Define normal, tangent, blendweight and depth here */
5393     static const DWORD vs_3_code[] = {
5394     0xfffe0300,                                                             /* vs_3_0                       */
5395     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5396     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5397     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5398     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5399     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5400     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5401     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5402     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5403     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5404     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5405     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5406     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5407     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5408     0x0000ffff                                                              /* end                          */
5409     };
5410     float quad1[] =  {
5411         -1.0,   -1.0,   0.1,
5412          0.0,   -1.0,   0.1,
5413         -1.0,    0.0,   0.1,
5414          0.0,    0.0,   0.1
5415     };
5416     float quad2[] =  {
5417          0.0,   -1.0,   0.1,
5418          1.0,   -1.0,   0.1,
5419          0.0,    0.0,   0.1,
5420          1.0,    0.0,   0.1
5421     };
5422     float quad3[] =  {
5423         -1.0,    0.0,   0.1,
5424          0.0,    0.0,   0.1,
5425         -1.0,    1.0,   0.1,
5426          0.0,    1.0,   0.1
5427     };
5428
5429     HRESULT hr;
5430     DWORD color;
5431     IDirect3DPixelShader9 *pixelshader = NULL;
5432     IDirect3DVertexShader9 *vs_1_shader = NULL;
5433     IDirect3DVertexShader9 *vs_2_shader = NULL;
5434     IDirect3DVertexShader9 *vs_3_shader = NULL;
5435
5436     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5437
5438     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5439     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5440     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5441     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5442     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5443     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5444     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5445     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5446     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5447     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5448     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5449
5450     hr = IDirect3DDevice9_BeginScene(device);
5451     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5452     if(SUCCEEDED(hr))
5453     {
5454         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5455         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5456         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5457         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5458
5459         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5460         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5461         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5462         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5463
5464         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5465         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5466         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5467         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5468
5469         hr = IDirect3DDevice9_EndScene(device);
5470         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5471     }
5472     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5473     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5474
5475     color = getPixelColor(device, 160, 120);
5476     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5477        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5478     color = getPixelColor(device, 160, 360);
5479     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5480        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5481     color = getPixelColor(device, 480, 360);
5482     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5483        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5484
5485     /* cleanup */
5486     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5487     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5488     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5489     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5490     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5491     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5492     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5493     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5494 }
5495
5496 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5497     static const DWORD vs_code[] = {
5498     0xfffe0300,                                                             /* vs_3_0                       */
5499     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5500     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5501     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5502     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5503     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5504     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5505     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5506     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5507     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5508     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5509     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5510     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5511     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5512
5513     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5514     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5515     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5516     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5517     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5518     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5519     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5520     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5521     0x0000ffff                                                              /* end                          */
5522     };
5523     static const DWORD ps_1_code[] = {
5524     0xffff0104,                                                             /* ps_1_4                       */
5525     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5526     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5527     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5528     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5529     0x0000ffff                                                              /* end                          */
5530     };
5531     static const DWORD ps_2_code[] = {
5532     0xffff0200,                                                             /* ps_2_0                       */
5533     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5534     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5535     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5536
5537     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5538     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5539     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5540     0x0000ffff                                                              /* end                          */
5541     };
5542     static const DWORD ps_3_code[] = {
5543     0xffff0300,                                                             /* ps_3_0                       */
5544     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5545     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5546     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5547
5548     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5549     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5550     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5551     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5552     0x0000ffff                                                              /* end                          */
5553     };
5554
5555     float quad1[] =  {
5556         -1.0,   -1.0,   0.1,
5557          0.0,   -1.0,   0.1,
5558         -1.0,    0.0,   0.1,
5559          0.0,    0.0,   0.1
5560     };
5561     float quad2[] =  {
5562          0.0,   -1.0,   0.1,
5563          1.0,   -1.0,   0.1,
5564          0.0,    0.0,   0.1,
5565          1.0,    0.0,   0.1
5566     };
5567     float quad3[] =  {
5568         -1.0,    0.0,   0.1,
5569          0.0,    0.0,   0.1,
5570         -1.0,    1.0,   0.1,
5571          0.0,    1.0,   0.1
5572     };
5573     float quad4[] =  {
5574          0.0,    0.0,   0.1,
5575          1.0,    0.0,   0.1,
5576          0.0,    1.0,   0.1,
5577          1.0,    1.0,   0.1
5578     };
5579
5580     HRESULT hr;
5581     DWORD color;
5582     IDirect3DVertexShader9 *vertexshader = NULL;
5583     IDirect3DPixelShader9 *ps_1_shader = NULL;
5584     IDirect3DPixelShader9 *ps_2_shader = NULL;
5585     IDirect3DPixelShader9 *ps_3_shader = NULL;
5586     IDirect3DTexture9 *texture = NULL;
5587     D3DLOCKED_RECT lr;
5588     unsigned int x, y;
5589
5590     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5591
5592     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5593     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5594     if(FAILED(hr)) {
5595         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5596         return;
5597     }
5598     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5599     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5600     for(y = 0; y < 512; y++) {
5601         for(x = 0; x < 512; x++) {
5602             double r_f = (double) x / (double) 512;
5603             double g_f = (double) y / (double) 512;
5604             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5605             unsigned short r = (unsigned short) (r_f * 65535.0);
5606             unsigned short g = (unsigned short) (g_f * 65535.0);
5607             dst[0] = r;
5608             dst[1] = g;
5609             dst[2] = 0;
5610             dst[3] = 65535;
5611         }
5612     }
5613     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5614     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5615
5616     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5617     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5618     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5619     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5620     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5621     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5622     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5623     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5624     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5625     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5626     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5627
5628     hr = IDirect3DDevice9_BeginScene(device);
5629     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5630     if(SUCCEEDED(hr))
5631     {
5632         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5633         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5635         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5636
5637         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5638         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5639         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5640         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5641
5642         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5643         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5644         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5645         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5646
5647         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5648         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5649         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5650         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5651         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5652         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5653         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5654         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5655         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5656         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5657
5658         hr = IDirect3DDevice9_EndScene(device);
5659         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5660     }
5661     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5662     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5663
5664     color = getPixelColor(device, 160, 120);
5665     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5666        (color & 0x0000ff00) == 0x0000ff00 &&
5667        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5668        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5669     color = getPixelColor(device, 160, 360);
5670     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5671        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5672        (color & 0x000000ff) == 0x00000000,
5673        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5674     color = getPixelColor(device, 480, 360);
5675     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5676        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5677        (color & 0x000000ff) == 0x00000000,
5678        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5679     color = getPixelColor(device, 480, 160);
5680     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5681        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5682        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5683        (color & 0x000000ff) == 0x00000000),
5684        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5685
5686     /* cleanup */
5687     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5688     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5689     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5690     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5691     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5692     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5693     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5694     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5695     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5696     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5697     if(texture) IDirect3DTexture9_Release(texture);
5698 }
5699
5700 void test_compare_instructions(IDirect3DDevice9 *device)
5701 {
5702     DWORD shader_sge_vec_code[] = {
5703         0xfffe0101,                                         /* vs_1_1                   */
5704         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5705         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5706         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5707         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5708         0x0000ffff                                          /* end                      */
5709     };
5710     DWORD shader_slt_vec_code[] = {
5711         0xfffe0101,                                         /* vs_1_1                   */
5712         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5713         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5714         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5715         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5716         0x0000ffff                                          /* end                      */
5717     };
5718     DWORD shader_sge_scalar_code[] = {
5719         0xfffe0101,                                         /* vs_1_1                   */
5720         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5721         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5722         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5723         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5724         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5725         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5726         0x0000ffff                                          /* end                      */
5727     };
5728     DWORD shader_slt_scalar_code[] = {
5729         0xfffe0101,                                         /* vs_1_1                   */
5730         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5731         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5732         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5733         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5734         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5735         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5736         0x0000ffff                                          /* end                      */
5737     };
5738     IDirect3DVertexShader9 *shader_sge_vec;
5739     IDirect3DVertexShader9 *shader_slt_vec;
5740     IDirect3DVertexShader9 *shader_sge_scalar;
5741     IDirect3DVertexShader9 *shader_slt_scalar;
5742     HRESULT hr, color;
5743     float quad1[] =  {
5744         -1.0,   -1.0,   0.1,
5745          0.0,   -1.0,   0.1,
5746         -1.0,    0.0,   0.1,
5747          0.0,    0.0,   0.1
5748     };
5749     float quad2[] =  {
5750          0.0,   -1.0,   0.1,
5751          1.0,   -1.0,   0.1,
5752          0.0,    0.0,   0.1,
5753          1.0,    0.0,   0.1
5754     };
5755     float quad3[] =  {
5756         -1.0,    0.0,   0.1,
5757          0.0,    0.0,   0.1,
5758         -1.0,    1.0,   0.1,
5759          0.0,    1.0,   0.1
5760     };
5761     float quad4[] =  {
5762          0.0,    0.0,   0.1,
5763          1.0,    0.0,   0.1,
5764          0.0,    1.0,   0.1,
5765          1.0,    1.0,   0.1
5766     };
5767     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5768     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5769
5770     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5771
5772     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5773     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5774     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5775     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5776     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5777     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5778     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5779     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5780     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5781     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5782     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5783     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5784     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5785     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5786
5787     hr = IDirect3DDevice9_BeginScene(device);
5788     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5789     if(SUCCEEDED(hr))
5790     {
5791         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5792         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5794         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5795
5796         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5797         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5798         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5799         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5800
5801         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5802         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5803         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5804         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5805
5806         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5807         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5808
5809         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5810         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5812         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5813
5814         hr = IDirect3DDevice9_EndScene(device);
5815         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5816     }
5817
5818     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5819     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5820     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5821     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5822
5823     color = getPixelColor(device, 160, 360);
5824     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5825     color = getPixelColor(device, 480, 360);
5826     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5827     color = getPixelColor(device, 160, 120);
5828     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5829     color = getPixelColor(device, 480, 160);
5830     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5831
5832     IDirect3DVertexShader9_Release(shader_sge_vec);
5833     IDirect3DVertexShader9_Release(shader_slt_vec);
5834     IDirect3DVertexShader9_Release(shader_sge_scalar);
5835     IDirect3DVertexShader9_Release(shader_slt_scalar);
5836 }
5837
5838 void test_vshader_input(IDirect3DDevice9 *device)
5839 {
5840     DWORD swapped_shader_code_3[] = {
5841         0xfffe0300,                                         /* vs_3_0               */
5842         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5843         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5844         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5845         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5846         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5847         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5848         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5849         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5850         0x0000ffff                                          /* end                  */
5851     };
5852     DWORD swapped_shader_code_1[] = {
5853         0xfffe0101,                                         /* vs_1_1               */
5854         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5855         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5856         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5857         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5858         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5859         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5860         0x0000ffff                                          /* end                  */
5861     };
5862     DWORD swapped_shader_code_2[] = {
5863         0xfffe0200,                                         /* vs_2_0               */
5864         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5865         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5866         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5867         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5868         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5869         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5870         0x0000ffff                                          /* end                  */
5871     };
5872     DWORD texcoord_color_shader_code_3[] = {
5873         0xfffe0300,                                         /* vs_3_0               */
5874         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5875         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5876         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5877         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5878         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5879         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5880         0x0000ffff                                          /* end                  */
5881     };
5882     DWORD texcoord_color_shader_code_2[] = {
5883         0xfffe0200,                                         /* vs_2_0               */
5884         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5885         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5886         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5887         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5888         0x0000ffff                                          /* end                  */
5889     };
5890     DWORD texcoord_color_shader_code_1[] = {
5891         0xfffe0101,                                         /* vs_1_1               */
5892         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5893         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5894         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5895         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5896         0x0000ffff                                          /* end                  */
5897     };
5898     DWORD color_color_shader_code_3[] = {
5899         0xfffe0300,                                         /* vs_3_0               */
5900         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5901         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5902         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5903         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5904         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5905         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5906         0x0000ffff                                          /* end                  */
5907     };
5908     DWORD color_color_shader_code_2[] = {
5909         0xfffe0200,                                         /* vs_2_0               */
5910         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5911         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5912         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5913         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5914         0x0000ffff                                          /* end                  */
5915     };
5916     DWORD color_color_shader_code_1[] = {
5917         0xfffe0101,                                         /* vs_1_1               */
5918         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5919         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5920         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5921         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5922         0x0000ffff                                          /* end                  */
5923     };
5924     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5925     HRESULT hr;
5926     DWORD color;
5927     float quad1[] =  {
5928         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5929          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5930         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5931          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5932     };
5933     float quad2[] =  {
5934          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5935          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5936          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5937          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
5938     };
5939     float quad3[] =  {
5940         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
5941          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
5942         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
5943          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
5944     };
5945     float quad4[] =  {
5946          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5947          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5948          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5949          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
5950     };
5951     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5952         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5953         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5954         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5955         D3DDECL_END()
5956     };
5957     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5958         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5959         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5960         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5961         D3DDECL_END()
5962     };
5963     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5964         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5965         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5966         D3DDECL_END()
5967     };
5968     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5969         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5970         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
5971         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
5972         D3DDECL_END()
5973     };
5974     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5975         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5976         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5977         D3DDECL_END()
5978     };
5979     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5980         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5981         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5982         D3DDECL_END()
5983     };
5984     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5985         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5986         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5987         D3DDECL_END()
5988     };
5989     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5990         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5991         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5992         D3DDECL_END()
5993     };
5994     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5995     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5996     unsigned int i;
5997     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5998     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5999
6000     struct vertex quad1_color[] =  {
6001        {-1.0,   -1.0,   0.1,    0x00ff8040},
6002        { 0.0,   -1.0,   0.1,    0x00ff8040},
6003        {-1.0,    0.0,   0.1,    0x00ff8040},
6004        { 0.0,    0.0,   0.1,    0x00ff8040}
6005     };
6006     struct vertex quad2_color[] =  {
6007        { 0.0,   -1.0,   0.1,    0x00ff8040},
6008        { 1.0,   -1.0,   0.1,    0x00ff8040},
6009        { 0.0,    0.0,   0.1,    0x00ff8040},
6010        { 1.0,    0.0,   0.1,    0x00ff8040}
6011     };
6012     struct vertex quad3_color[] =  {
6013        {-1.0,    0.0,   0.1,    0x00ff8040},
6014        { 0.0,    0.0,   0.1,    0x00ff8040},
6015        {-1.0,    1.0,   0.1,    0x00ff8040},
6016        { 0.0,    1.0,   0.1,    0x00ff8040}
6017     };
6018     float quad4_color[] =  {
6019          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6020          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6021          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6022          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6023     };
6024
6025     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6026     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6027     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6028     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6029     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6030     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6031     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6032     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6033
6034     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6035     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6036     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6037     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6038     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6039     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6040     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6041     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6042
6043     for(i = 1; i <= 3; i++) {
6044         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6045         if(i == 3) {
6046             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6047             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6048         } else if(i == 2){
6049             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6050             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6051         } else if(i == 1) {
6052             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6053             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6054         }
6055
6056         hr = IDirect3DDevice9_BeginScene(device);
6057         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6058         if(SUCCEEDED(hr))
6059         {
6060             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6061             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6062
6063             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6064             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6065             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6066             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6067
6068             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6069             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6070             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6071             if(i == 3 || i == 2) {
6072                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6073             } else if(i == 1) {
6074                 /* Succeeds or fails, depending on SW or HW vertex processing */
6075                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6076             }
6077
6078             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6079             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6080             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6081             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6082
6083             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6084             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6085             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6086             if(i == 3 || i == 2) {
6087                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6088             } else if(i == 1) {
6089                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6090             }
6091
6092             hr = IDirect3DDevice9_EndScene(device);
6093             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6094         }
6095
6096         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6097         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6098
6099         if(i == 3 || i == 2) {
6100             color = getPixelColor(device, 160, 360);
6101             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6102                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6103
6104             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6105             color = getPixelColor(device, 480, 360);
6106             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6107                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6108             color = getPixelColor(device, 160, 120);
6109             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6110             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6111                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6112
6113             color = getPixelColor(device, 480, 160);
6114             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6115         } else if(i == 1) {
6116             color = getPixelColor(device, 160, 360);
6117             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6118                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6119             color = getPixelColor(device, 480, 360);
6120             /* Accept the clear color as well in this case, since SW VP returns an error */
6121             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6122             color = getPixelColor(device, 160, 120);
6123             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6124                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6125             color = getPixelColor(device, 480, 160);
6126             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6127         }
6128
6129         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6130         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6131
6132         /* Now find out if the whole streams are re-read, or just the last active value for the
6133          * vertices is used.
6134          */
6135         hr = IDirect3DDevice9_BeginScene(device);
6136         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6137         if(SUCCEEDED(hr))
6138         {
6139             float quad1_modified[] =  {
6140                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6141                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6142                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6143                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6144             };
6145             float quad2_modified[] =  {
6146                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6147                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6148                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6149                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6150             };
6151
6152             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6153             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6154
6155             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6156             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6157             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6158             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6159
6160             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6161             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6162             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6163             if(i == 3 || i == 2) {
6164                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6165             } else if(i == 1) {
6166                 /* Succeeds or fails, depending on SW or HW vertex processing */
6167                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6168             }
6169
6170             hr = IDirect3DDevice9_EndScene(device);
6171             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6172         }
6173         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6174         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6175
6176         color = getPixelColor(device, 480, 350);
6177         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6178          * as well.
6179          *
6180          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6181          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6182          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6183          * refrast's result.
6184          *
6185          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6186          */
6187         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6188            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6189         color = getPixelColor(device, 160, 120);
6190
6191         IDirect3DDevice9_SetVertexShader(device, NULL);
6192         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6193
6194         IDirect3DVertexShader9_Release(swapped_shader);
6195     }
6196
6197     for(i = 1; i <= 3; i++) {
6198         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6199         if(i == 3) {
6200             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6201             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6202             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6203             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6204         } else if(i == 2){
6205             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6206             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6207             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6208             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6209         } else if(i == 1) {
6210             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6212             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6213             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6214         }
6215
6216         hr = IDirect3DDevice9_BeginScene(device);
6217         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6218         if(SUCCEEDED(hr))
6219         {
6220             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6221             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6222             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6223             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6224             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6225             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6226
6227             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6228             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6229
6230             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6231             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6232             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6233             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6234             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6235             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6236
6237             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6238             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6239             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6240             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6241             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6242             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6243
6244             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6245             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6246             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6247             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6248
6249             hr = IDirect3DDevice9_EndScene(device);
6250             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6251         }
6252         IDirect3DDevice9_SetVertexShader(device, NULL);
6253         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6254
6255         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6256         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6257
6258         color = getPixelColor(device, 160, 360);
6259         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6260            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6261         color = getPixelColor(device, 480, 360);
6262         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6263            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6264         color = getPixelColor(device, 160, 120);
6265         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6266            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6267         color = getPixelColor(device, 480, 160);
6268         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6269            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6270
6271         IDirect3DVertexShader9_Release(texcoord_color_shader);
6272         IDirect3DVertexShader9_Release(color_color_shader);
6273     }
6274
6275     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6276     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6277     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6278     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6279
6280     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6281     IDirect3DVertexDeclaration9_Release(decl_color_color);
6282     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6283     IDirect3DVertexDeclaration9_Release(decl_color_float);
6284 }
6285
6286 static void srgbtexture_test(IDirect3DDevice9 *device)
6287 {
6288     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6289      * texture stage state to render a quad using that texture.  The resulting
6290      * color components should be 0x36 (~ 0.21), per this formula:
6291      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6292      * This is true where srgb_color > 0.04045.
6293      */
6294     IDirect3D9 *d3d = NULL;
6295     HRESULT hr;
6296     LPDIRECT3DTEXTURE9 texture = NULL;
6297     LPDIRECT3DSURFACE9 surface = NULL;
6298     D3DLOCKED_RECT lr;
6299     DWORD color;
6300     float quad[] = {
6301         -1.0,       1.0,       0.0,     0.0,    0.0,
6302          1.0,       1.0,       0.0,     1.0,    0.0,
6303         -1.0,      -1.0,       0.0,     0.0,    1.0,
6304          1.0,      -1.0,       0.0,     1.0,    1.0,
6305     };
6306
6307
6308     memset(&lr, 0, sizeof(lr));
6309     IDirect3DDevice9_GetDirect3D(device, &d3d);
6310     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6311                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6312                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6313         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6314         goto out;
6315     }
6316
6317     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6318                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6319                                         &texture, NULL);
6320     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6321     if(!texture) {
6322         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6323         goto out;
6324     }
6325     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6326     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6327
6328     fill_surface(surface, 0xff7f7f7f);
6329     IDirect3DSurface9_Release(surface);
6330
6331     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6332     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6333     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6334     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6335
6336     hr = IDirect3DDevice9_BeginScene(device);
6337     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6338     if(SUCCEEDED(hr))
6339     {
6340         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6341         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6342
6343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6345
6346
6347         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6348         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6349
6350         hr = IDirect3DDevice9_EndScene(device);
6351         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6352     }
6353
6354     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6355     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6356     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6357     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6358
6359     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6360     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6361
6362     color = getPixelColor(device, 320, 240);
6363     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6364
6365 out:
6366     if(texture) IDirect3DTexture9_Release(texture);
6367     IDirect3D9_Release(d3d);
6368 }
6369
6370 static void shademode_test(IDirect3DDevice9 *device)
6371 {
6372     /* Render a quad and try all of the different fixed function shading models. */
6373     HRESULT hr;
6374     DWORD color0, color1;
6375     DWORD color0_gouraud = 0, color1_gouraud = 0;
6376     DWORD shademode = D3DSHADE_FLAT;
6377     DWORD primtype = D3DPT_TRIANGLESTRIP;
6378     LPVOID data = NULL;
6379     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6380     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6381     UINT i, j;
6382     struct vertex quad_strip[] =
6383     {
6384         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6385         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6386         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6387         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6388     };
6389     struct vertex quad_list[] =
6390     {
6391         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6392         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6393         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6394
6395         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6396         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6397         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6398     };
6399
6400     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6401                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6402     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6403     if (FAILED(hr)) goto bail;
6404
6405     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6406                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6407     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6408     if (FAILED(hr)) goto bail;
6409
6410     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6411     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6412
6413     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6414     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6415
6416     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6417     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6418     memcpy(data, quad_strip, sizeof(quad_strip));
6419     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6420     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6421
6422     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6423     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6424     memcpy(data, quad_list, sizeof(quad_list));
6425     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6426     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6427
6428     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6429      * the color fixups we have to do for FLAT shading will be dependent on that. */
6430     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6431     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6432
6433     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6434     for (j=0; j<2; j++) {
6435
6436         /* Inner loop just changes the D3DRS_SHADEMODE */
6437         for (i=0; i<3; i++) {
6438             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6439             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6440
6441             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6442             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6443
6444             hr = IDirect3DDevice9_BeginScene(device);
6445             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6446             if(SUCCEEDED(hr))
6447             {
6448                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6449                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6450
6451                 hr = IDirect3DDevice9_EndScene(device);
6452                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6453             }
6454
6455             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6456             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6457
6458             /* Sample two spots from the output */
6459             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6460             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6461             switch(shademode) {
6462                 case D3DSHADE_FLAT:
6463                     /* Should take the color of the first vertex of each triangle */
6464                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6465                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6466                     shademode = D3DSHADE_GOURAUD;
6467                     break;
6468                 case D3DSHADE_GOURAUD:
6469                     /* Should be an interpolated blend */
6470
6471                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6472                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6473                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6474                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6475
6476                     color0_gouraud = color0;
6477                     color1_gouraud = color1;
6478
6479                     shademode = D3DSHADE_PHONG;
6480                     break;
6481                 case D3DSHADE_PHONG:
6482                     /* Should be the same as GOURAUD, since no hardware implements this */
6483                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6484                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6485                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6486                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6487
6488                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6489                             color0_gouraud, color0);
6490                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6491                             color1_gouraud, color1);
6492                     break;
6493             }
6494         }
6495         /* Now, do it all over again with a TRIANGLELIST */
6496         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6497         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6498         primtype = D3DPT_TRIANGLELIST;
6499         shademode = D3DSHADE_FLAT;
6500     }
6501
6502 bail:
6503     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6504     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6505     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6507
6508     if (vb_strip)
6509         IDirect3DVertexBuffer9_Release(vb_strip);
6510     if (vb_list)
6511         IDirect3DVertexBuffer9_Release(vb_list);
6512 }
6513
6514
6515 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6516 {
6517     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6518      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6519      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6520      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6521      * 0.73
6522      *
6523      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6524      * so use shaders for this task
6525      */
6526     IDirect3DPixelShader9 *pshader;
6527     IDirect3DVertexShader9 *vshader;
6528     IDirect3D9 *d3d;
6529     DWORD vshader_code[] = {
6530         0xfffe0101,                                                             /* vs_1_1                       */
6531         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6532         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6533         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6534         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6535         0x0000ffff                                                              /* end                          */
6536     };
6537     DWORD pshader_code[] = {
6538         0xffff0101,                                                             /* ps_1_1                       */
6539         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6540         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6541         0x0000ffff                                                              /* end                          */
6542     };
6543     const float quad[] = {
6544        -1.0,   -1.0,    0.1,
6545         1.0,   -1.0,    0.1,
6546        -1.0,    1.0,    0.1,
6547         1.0,    1.0,    0.1
6548     };
6549     HRESULT hr;
6550     DWORD color;
6551
6552     IDirect3DDevice9_GetDirect3D(device, &d3d);
6553     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6554      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6555      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6556      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6557      * works
6558      */
6559     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6560                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6561                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6562         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6563         IDirect3D9_Release(d3d);
6564         return;
6565     }
6566     IDirect3D9_Release(d3d);
6567
6568     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6569     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6570
6571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6572     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6574     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6576     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6577     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6578     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6579     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6580     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6581
6582     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6583     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6584     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6585     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6586     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6587     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6588     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6589     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6590     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6591     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6592
6593     hr = IDirect3DDevice9_BeginScene(device);
6594     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6595     if(SUCCEEDED(hr)) {
6596         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6597         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6598
6599         hr = IDirect3DDevice9_EndScene(device);
6600         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6601     }
6602
6603     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6604     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6605     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6606     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6607     IDirect3DPixelShader9_Release(pshader);
6608     IDirect3DVertexShader9_Release(vshader);
6609
6610     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6611     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6612     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6613     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6614
6615     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6616     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6617     color = getPixelColor(device, 160, 360);
6618     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6619        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6620 }
6621
6622 static void alpha_test(IDirect3DDevice9 *device)
6623 {
6624     HRESULT hr;
6625     IDirect3DTexture9 *offscreenTexture;
6626     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6627     DWORD color;
6628
6629     struct vertex quad1[] =
6630     {
6631         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6632         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6633         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6634         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6635     };
6636     struct vertex quad2[] =
6637     {
6638         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6639         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6640         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6641         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6642     };
6643     static const float composite_quad[][5] = {
6644         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6645         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6646         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6647         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6648     };
6649
6650     /* Clear the render target with alpha = 0.5 */
6651     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6652     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6653
6654     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6655     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6656
6657     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6658     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6659     if(!backbuffer) {
6660         goto out;
6661     }
6662
6663     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6664     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6665     if(!offscreen) {
6666         goto out;
6667     }
6668
6669     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6670     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6671
6672     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6673     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6674     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6675     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6676     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6677     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6678     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6679     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6680     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6681     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6682
6683     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6684     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6685     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6686
6687         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6688         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6689         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6690         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6691         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6693         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6694
6695         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6696         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6697         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6698         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6699         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6700         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6701
6702         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6703          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6704          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6705         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6706         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6707         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6708         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6709
6710         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6711         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6712         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6713         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6714         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6715         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6716
6717         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6718         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6719         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6720         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6721         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6722         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6723
6724         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6725         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6726
6727         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6728          * Disable alpha blending for the final composition
6729          */
6730         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6731         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6732         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6733         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6734
6735         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6736         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6737         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6738         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6739         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6740         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6741
6742         hr = IDirect3DDevice9_EndScene(device);
6743         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6744     }
6745
6746     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6747
6748     color = getPixelColor(device, 160, 360);
6749     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6750        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6751
6752     color = getPixelColor(device, 160, 120);
6753     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6754        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6755
6756     color = getPixelColor(device, 480, 360);
6757     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6758        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6759
6760     color = getPixelColor(device, 480, 120);
6761     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6762        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6763
6764     out:
6765     /* restore things */
6766     if(backbuffer) {
6767         IDirect3DSurface9_Release(backbuffer);
6768     }
6769     if(offscreenTexture) {
6770         IDirect3DTexture9_Release(offscreenTexture);
6771     }
6772     if(offscreen) {
6773         IDirect3DSurface9_Release(offscreen);
6774     }
6775 }
6776
6777 struct vertex_shortcolor {
6778     float x, y, z;
6779     unsigned short r, g, b, a;
6780 };
6781 struct vertex_floatcolor {
6782     float x, y, z;
6783     float r, g, b, a;
6784 };
6785
6786 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6787 {
6788     HRESULT hr;
6789     BOOL s_ok, ub_ok, f_ok;
6790     DWORD color, size, i;
6791     void *data;
6792     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6793         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6794         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6795         D3DDECL_END()
6796     };
6797     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6798         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6799         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6800         D3DDECL_END()
6801     };
6802     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6803         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6804         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6805         D3DDECL_END()
6806     };
6807     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6808         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6809         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6810         D3DDECL_END()
6811     };
6812     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6813         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6814         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6815         D3DDECL_END()
6816     };
6817     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6818         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6819         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6820         D3DDECL_END()
6821     };
6822     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6823         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6824         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6825         D3DDECL_END()
6826     };
6827     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6828     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6829     IDirect3DVertexBuffer9 *vb, *vb2;
6830     struct vertex quad1[] =                             /* D3DCOLOR */
6831     {
6832         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6833         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6834         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6835         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6836     };
6837     struct vertex quad2[] =                             /* UBYTE4N */
6838     {
6839         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6840         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6841         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6842         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6843     };
6844     struct vertex_shortcolor quad3[] =                  /* short */
6845     {
6846         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6847         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6848         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6849         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6850     };
6851     struct vertex_floatcolor quad4[] =
6852     {
6853         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6854         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6855         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6856         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6857     };
6858     DWORD colors[] = {
6859         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6860         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6861         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
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     };
6876     float quads[] = {
6877         -1.0,   -1.0,     0.1,
6878         -1.0,    0.0,     0.1,
6879          0.0,   -1.0,     0.1,
6880          0.0,    0.0,     0.1,
6881
6882          0.0,   -1.0,     0.1,
6883          0.0,    0.0,     0.1,
6884          1.0,   -1.0,     0.1,
6885          1.0,    0.0,     0.1,
6886
6887          0.0,    0.0,     0.1,
6888          0.0,    1.0,     0.1,
6889          1.0,    0.0,     0.1,
6890          1.0,    1.0,     0.1,
6891
6892         -1.0,    0.0,     0.1,
6893         -1.0,    1.0,     0.1,
6894          0.0,    0.0,     0.1,
6895          0.0,    1.0,     0.1
6896     };
6897     struct tvertex quad_transformed[] = {
6898        {  90,    110,     0.1,      2.0,        0x00ffff00},
6899        { 570,    110,     0.1,      2.0,        0x00ffff00},
6900        {  90,    300,     0.1,      2.0,        0x00ffff00},
6901        { 570,    300,     0.1,      2.0,        0x00ffff00}
6902     };
6903     D3DCAPS9 caps;
6904
6905     memset(&caps, 0, sizeof(caps));
6906     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6907     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6908
6909     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6910     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6911
6912     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6913     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6914     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6915     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6916     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6917     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6918     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6919         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6920         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6921         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6922         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6923     } else {
6924         trace("D3DDTCAPS_UBYTE4N not supported\n");
6925         dcl_ubyte_2 = NULL;
6926         dcl_ubyte = NULL;
6927     }
6928     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6929     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6930     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6931     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6932
6933     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6934     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6935                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6936     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6937
6938     hr = IDirect3DDevice9_BeginScene(device);
6939     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6940     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6941     if(SUCCEEDED(hr)) {
6942         if(dcl_color) {
6943             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6944             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6945             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6946             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6947         }
6948
6949         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6950          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6951          * using software vertex processing. Doh!
6952          */
6953         if(dcl_ubyte) {
6954             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6955             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6956             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6957             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6958             ub_ok = SUCCEEDED(hr);
6959         }
6960
6961         if(dcl_short) {
6962             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6963             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6964             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6965             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6966             s_ok = SUCCEEDED(hr);
6967         }
6968
6969         if(dcl_float) {
6970             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6971             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6972             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6973             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6974             f_ok = SUCCEEDED(hr);
6975         }
6976
6977         hr = IDirect3DDevice9_EndScene(device);
6978         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6979     }
6980
6981     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6982     if(dcl_short) {
6983         color = getPixelColor(device, 480, 360);
6984         ok(color == 0x000000ff || !s_ok,
6985            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6986     }
6987     if(dcl_ubyte) {
6988         color = getPixelColor(device, 160, 120);
6989         ok(color == 0x0000ffff || !ub_ok,
6990            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6991     }
6992     if(dcl_color) {
6993         color = getPixelColor(device, 160, 360);
6994         ok(color == 0x00ffff00,
6995            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
6996     }
6997     if(dcl_float) {
6998         color = getPixelColor(device, 480, 120);
6999         ok(color == 0x00ff0000 || !f_ok,
7000            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7001     }
7002
7003     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7004      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7005      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7006      * whether the immediate mode code works
7007      */
7008     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7009     hr = IDirect3DDevice9_BeginScene(device);
7010     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7011     if(SUCCEEDED(hr)) {
7012         if(dcl_color) {
7013             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7014             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7015             memcpy(data, quad1, sizeof(quad1));
7016             hr = IDirect3DVertexBuffer9_Unlock(vb);
7017             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7018             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7019             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7020             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7021             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7022             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7023             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7024         }
7025
7026         if(dcl_ubyte) {
7027             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7028             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7029             memcpy(data, quad2, sizeof(quad2));
7030             hr = IDirect3DVertexBuffer9_Unlock(vb);
7031             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7032             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7033             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7034             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7035             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7036             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7037             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7038                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7039             ub_ok = SUCCEEDED(hr);
7040         }
7041
7042         if(dcl_short) {
7043             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7044             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7045             memcpy(data, quad3, sizeof(quad3));
7046             hr = IDirect3DVertexBuffer9_Unlock(vb);
7047             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7048             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7049             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7051             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7052             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7053             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7054                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7055             s_ok = SUCCEEDED(hr);
7056         }
7057
7058         if(dcl_float) {
7059             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7060             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7061             memcpy(data, quad4, sizeof(quad4));
7062             hr = IDirect3DVertexBuffer9_Unlock(vb);
7063             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7064             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7065             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7066             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7067             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7068             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7069             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7070                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7071             f_ok = SUCCEEDED(hr);
7072         }
7073
7074         hr = IDirect3DDevice9_EndScene(device);
7075         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7076     }
7077
7078     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7079     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7080     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7081     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7082
7083     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7084     if(dcl_short) {
7085         color = getPixelColor(device, 480, 360);
7086         ok(color == 0x000000ff || !s_ok,
7087            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7088     }
7089     if(dcl_ubyte) {
7090         color = getPixelColor(device, 160, 120);
7091         ok(color == 0x0000ffff || !ub_ok,
7092            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7093     }
7094     if(dcl_color) {
7095         color = getPixelColor(device, 160, 360);
7096         ok(color == 0x00ffff00,
7097            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7098     }
7099     if(dcl_float) {
7100         color = getPixelColor(device, 480, 120);
7101         ok(color == 0x00ff0000 || !f_ok,
7102            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7103     }
7104
7105     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7106     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7107
7108     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7109     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7110     memcpy(data, quad_transformed, sizeof(quad_transformed));
7111     hr = IDirect3DVertexBuffer9_Unlock(vb);
7112     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7113
7114     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7115     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7116
7117     hr = IDirect3DDevice9_BeginScene(device);
7118     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7119     if(SUCCEEDED(hr)) {
7120         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7121         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7122         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7123         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7124
7125         hr = IDirect3DDevice9_EndScene(device);
7126         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7127     }
7128
7129     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7130     color = getPixelColor(device, 88, 108);
7131     ok(color == 0x000000ff,
7132        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7133     color = getPixelColor(device, 92, 108);
7134     ok(color == 0x000000ff,
7135        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7136     color = getPixelColor(device, 88, 112);
7137     ok(color == 0x000000ff,
7138        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7139     color = getPixelColor(device, 92, 112);
7140     ok(color == 0x00ffff00,
7141        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7142
7143     color = getPixelColor(device, 568, 108);
7144     ok(color == 0x000000ff,
7145        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7146     color = getPixelColor(device, 572, 108);
7147     ok(color == 0x000000ff,
7148        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7149     color = getPixelColor(device, 568, 112);
7150     ok(color == 0x00ffff00,
7151        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7152     color = getPixelColor(device, 572, 112);
7153     ok(color == 0x000000ff,
7154        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7155
7156     color = getPixelColor(device, 88, 298);
7157     ok(color == 0x000000ff,
7158        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7159     color = getPixelColor(device, 92, 298);
7160     ok(color == 0x00ffff00,
7161        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7162     color = getPixelColor(device, 88, 302);
7163     ok(color == 0x000000ff,
7164        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7165     color = getPixelColor(device, 92, 302);
7166     ok(color == 0x000000ff,
7167        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7168
7169     color = getPixelColor(device, 568, 298);
7170     ok(color == 0x00ffff00,
7171        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7172     color = getPixelColor(device, 572, 298);
7173     ok(color == 0x000000ff,
7174        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7175     color = getPixelColor(device, 568, 302);
7176     ok(color == 0x000000ff,
7177        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7178     color = getPixelColor(device, 572, 302);
7179     ok(color == 0x000000ff,
7180        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7181
7182     /* This test is pointless without those two declarations: */
7183     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7184         skip("color-ubyte switching test declarations aren't supported\n");
7185         goto out;
7186     }
7187
7188     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7189     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7190     memcpy(data, quads, sizeof(quads));
7191     hr = IDirect3DVertexBuffer9_Unlock(vb);
7192     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7193     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7194                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7195     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7196     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7197     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7198     memcpy(data, colors, sizeof(colors));
7199     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7200     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7201
7202     for(i = 0; i < 2; i++) {
7203         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7204         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7205
7206         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7207         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7208         if(i == 0) {
7209             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7210         } else {
7211             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7212         }
7213         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7214
7215         hr = IDirect3DDevice9_BeginScene(device);
7216         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7217         ub_ok = FALSE;
7218         if(SUCCEEDED(hr)) {
7219             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7220             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7221             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7222             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7223                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7224             ub_ok = SUCCEEDED(hr);
7225
7226             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7227             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7228             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7229             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7230
7231             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7232             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7233             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7234             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7235                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7236             ub_ok = (SUCCEEDED(hr) && ub_ok);
7237
7238             hr = IDirect3DDevice9_EndScene(device);
7239             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7240         }
7241
7242         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7243         if(i == 0) {
7244             color = getPixelColor(device, 480, 360);
7245             ok(color == 0x00ff0000,
7246                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7247             color = getPixelColor(device, 160, 120);
7248             ok(color == 0x00ffffff,
7249                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7250             color = getPixelColor(device, 160, 360);
7251             ok(color == 0x000000ff || !ub_ok,
7252                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7253             color = getPixelColor(device, 480, 120);
7254             ok(color == 0x000000ff || !ub_ok,
7255                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7256         } else {
7257             color = getPixelColor(device, 480, 360);
7258             ok(color == 0x000000ff,
7259                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7260             color = getPixelColor(device, 160, 120);
7261             ok(color == 0x00ffffff,
7262                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7263             color = getPixelColor(device, 160, 360);
7264             ok(color == 0x00ff0000 || !ub_ok,
7265                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7266             color = getPixelColor(device, 480, 120);
7267             ok(color == 0x00ff0000 || !ub_ok,
7268                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7269         }
7270     }
7271
7272     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7273     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7274     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7275     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7276     IDirect3DVertexBuffer9_Release(vb2);
7277
7278     out:
7279     IDirect3DVertexBuffer9_Release(vb);
7280     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7281     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7282     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7283     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7284     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7285     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7286     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7287 }
7288
7289 struct vertex_float16color {
7290     float x, y, z;
7291     DWORD c1, c2;
7292 };
7293
7294 static void test_vshader_float16(IDirect3DDevice9 *device)
7295 {
7296     HRESULT hr;
7297     DWORD color;
7298     void *data;
7299     static const D3DVERTEXELEMENT9 decl_elements[] = {
7300         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7301         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7302         D3DDECL_END()
7303     };
7304     IDirect3DVertexDeclaration9 *vdecl = NULL;
7305     IDirect3DVertexBuffer9 *buffer = NULL;
7306     IDirect3DVertexShader9 *shader;
7307     DWORD shader_code[] = {
7308         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7309         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7310         0x90e40001, 0x0000ffff
7311     };
7312     struct vertex_float16color quad[] = {
7313         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7314         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7315         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7316         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7317
7318         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7319         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7320         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7321         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7322
7323         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7324         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7325         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7326         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7327
7328         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7329         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7330         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7331         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7332     };
7333
7334     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7335     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7336
7337     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7338     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7339     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7340     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7341     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7342     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7343
7344     hr = IDirect3DDevice9_BeginScene(device);
7345     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7346     if(SUCCEEDED(hr)) {
7347         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7348         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7349         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7350         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7351         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7352         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7353         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7354         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7356         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7357
7358         hr = IDirect3DDevice9_EndScene(device);
7359         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7360     }
7361     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7362     color = getPixelColor(device, 480, 360);
7363     ok(color == 0x00ff0000,
7364        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7365     color = getPixelColor(device, 160, 120);
7366     ok(color == 0x00000000,
7367        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7368     color = getPixelColor(device, 160, 360);
7369     ok(color == 0x0000ff00,
7370        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7371     color = getPixelColor(device, 480, 120);
7372     ok(color == 0x000000ff,
7373        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7374
7375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7377
7378     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7379                                              D3DPOOL_MANAGED, &buffer, NULL);
7380     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7381     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7382     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7383     memcpy(data, quad, sizeof(quad));
7384     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7385     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7386     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7387     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7388
7389     hr = IDirect3DDevice9_BeginScene(device);
7390     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7391     if(SUCCEEDED(hr)) {
7392             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7393             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7394             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7395             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7396             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7397             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7398             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7399             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7400
7401             hr = IDirect3DDevice9_EndScene(device);
7402             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7403     }
7404
7405     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7406     color = getPixelColor(device, 480, 360);
7407     ok(color == 0x00ff0000,
7408        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7409     color = getPixelColor(device, 160, 120);
7410     ok(color == 0x00000000,
7411        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7412     color = getPixelColor(device, 160, 360);
7413     ok(color == 0x0000ff00,
7414        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7415     color = getPixelColor(device, 480, 120);
7416     ok(color == 0x000000ff,
7417        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7418
7419     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7420     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7421     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7422     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7423     IDirect3DDevice9_SetVertexShader(device, NULL);
7424     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7425
7426     IDirect3DVertexDeclaration9_Release(vdecl);
7427     IDirect3DVertexShader9_Release(shader);
7428     IDirect3DVertexBuffer9_Release(buffer);
7429 }
7430
7431 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7432 {
7433     D3DCAPS9 caps;
7434     IDirect3DTexture9 *texture;
7435     HRESULT hr;
7436     D3DLOCKED_RECT rect;
7437     unsigned int x, y;
7438     DWORD *dst, color;
7439     const float quad[] = {
7440         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7441          1.0,   -1.0,   0.1,    1.2,   -0.2,
7442         -1.0,    1.0,   0.1,   -0.2,    1.2,
7443          1.0,    1.0,   0.1,    1.2,    1.2
7444     };
7445     memset(&caps, 0, sizeof(caps));
7446
7447     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7448     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7449     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7450         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7451         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7452            "Card has conditional NP2 support without power of two restriction set\n");
7453         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7454         return;
7455     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7456         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7457         return;
7458     }
7459
7460     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7461     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7462
7463     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7464     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7465
7466     memset(&rect, 0, sizeof(rect));
7467     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7468     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7469     for(y = 0; y < 10; y++) {
7470         for(x = 0; x < 10; x++) {
7471             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7472             if(x == 0 || x == 9 || y == 0 || y == 9) {
7473                 *dst = 0x00ff0000;
7474             } else {
7475                 *dst = 0x000000ff;
7476             }
7477         }
7478     }
7479     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7480     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7481
7482     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7483     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7484     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7485     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7486     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7487     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7488     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7489     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7490
7491     hr = IDirect3DDevice9_BeginScene(device);
7492     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7493     if(SUCCEEDED(hr)) {
7494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7495         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7496
7497         hr = IDirect3DDevice9_EndScene(device);
7498         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7499     }
7500
7501     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7502
7503     color = getPixelColor(device,    1,  1);
7504     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7505     color = getPixelColor(device, 639, 479);
7506     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7507
7508     color = getPixelColor(device, 135, 101);
7509     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7510     color = getPixelColor(device, 140, 101);
7511     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7512     color = getPixelColor(device, 135, 105);
7513     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7514     color = getPixelColor(device, 140, 105);
7515     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7516
7517     color = getPixelColor(device, 135, 376);
7518     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7519     color = getPixelColor(device, 140, 376);
7520     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7521     color = getPixelColor(device, 135, 379);
7522     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7523     color = getPixelColor(device, 140, 379);
7524     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7525
7526     color = getPixelColor(device, 500, 101);
7527     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7528     color = getPixelColor(device, 504, 101);
7529     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7530     color = getPixelColor(device, 500, 105);
7531     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7532     color = getPixelColor(device, 504, 105);
7533     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7534
7535     color = getPixelColor(device, 500, 376);
7536     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7537     color = getPixelColor(device, 504, 376);
7538     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7539     color = getPixelColor(device, 500, 380);
7540     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7541     color = getPixelColor(device, 504, 380);
7542     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7543
7544     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7545     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7546     IDirect3DTexture9_Release(texture);
7547 }
7548
7549 static void vFace_register_test(IDirect3DDevice9 *device)
7550 {
7551     HRESULT hr;
7552     DWORD color;
7553     const DWORD shader_code[] = {
7554         0xffff0300,                                                             /* ps_3_0                     */
7555         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7556         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7557         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7558         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7559         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7560         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7561         0x0000ffff                                                              /* END                        */
7562     };
7563     IDirect3DPixelShader9 *shader;
7564     IDirect3DTexture9 *texture;
7565     IDirect3DSurface9 *surface, *backbuffer;
7566     const float quad[] = {
7567         -1.0,   -1.0,   0.1,
7568          1.0,   -1.0,   0.1,
7569         -1.0,    0.0,   0.1,
7570
7571          1.0,   -1.0,   0.1,
7572          1.0,    0.0,   0.1,
7573         -1.0,    0.0,   0.1,
7574
7575         -1.0,    0.0,   0.1,
7576         -1.0,    1.0,   0.1,
7577          1.0,    0.0,   0.1,
7578
7579          1.0,    0.0,   0.1,
7580         -1.0,    1.0,   0.1,
7581          1.0,    1.0,   0.1,
7582     };
7583     const float blit[] = {
7584          0.0,   -1.0,   0.1,    0.0,    0.0,
7585          1.0,   -1.0,   0.1,    1.0,    0.0,
7586          0.0,    1.0,   0.1,    0.0,    1.0,
7587          1.0,    1.0,   0.1,    1.0,    1.0,
7588     };
7589
7590     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7591     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7592     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7593     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7594     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7595     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7596     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7597     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7598     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7599     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7600     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7601     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7602
7603     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7604     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7605
7606     hr = IDirect3DDevice9_BeginScene(device);
7607     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7608     if(SUCCEEDED(hr)) {
7609         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7610         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7611         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7612         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7613         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7614         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7615         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7616         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7617         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7618         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7619         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7620
7621         /* Blit the texture onto the back buffer to make it visible */
7622         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7623         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7624         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7625         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7626         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7627         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7628         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7629         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7630         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7631         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7632
7633         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7634         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7635
7636         hr = IDirect3DDevice9_EndScene(device);
7637         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7638     }
7639
7640     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7641     color = getPixelColor(device, 160, 360);
7642     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7643     color = getPixelColor(device, 160, 120);
7644     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7645     color = getPixelColor(device, 480, 360);
7646     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7647     color = getPixelColor(device, 480, 120);
7648     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7649
7650     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7651     IDirect3DDevice9_SetTexture(device, 0, NULL);
7652     IDirect3DPixelShader9_Release(shader);
7653     IDirect3DSurface9_Release(surface);
7654     IDirect3DSurface9_Release(backbuffer);
7655     IDirect3DTexture9_Release(texture);
7656 }
7657
7658 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7659 {
7660     HRESULT hr;
7661     DWORD color;
7662     int i;
7663     D3DCAPS9 caps;
7664     BOOL L6V5U5_supported = FALSE;
7665     IDirect3DTexture9 *tex1, *tex2;
7666     D3DLOCKED_RECT locked_rect;
7667
7668     static const float quad[][7] = {
7669         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7670         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7671         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7672         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7673     };
7674
7675     static const D3DVERTEXELEMENT9 decl_elements[] = {
7676         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7677         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7678         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7679         D3DDECL_END()
7680     };
7681
7682     /* use asymmetric matrix to test loading */
7683     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7684     float scale, offset;
7685
7686     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7687     IDirect3DTexture9           *texture            = NULL;
7688
7689     memset(&caps, 0, sizeof(caps));
7690     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7691     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7692     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7693         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7694         return;
7695     } else {
7696         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7697          * They report that it is not supported, but after that bump mapping works properly. So just test
7698          * if the format is generally supported, and check the BUMPENVMAP flag
7699          */
7700         IDirect3D9 *d3d9;
7701
7702         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7703         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7704                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7705         L6V5U5_supported = SUCCEEDED(hr);
7706         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7707                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7708         IDirect3D9_Release(d3d9);
7709         if(FAILED(hr)) {
7710             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7711             return;
7712         }
7713     }
7714
7715     /* Generate the textures */
7716     generate_bumpmap_textures(device);
7717
7718     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7719     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7720     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7721     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7722     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7723     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7724     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7725     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7726
7727     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7728     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7729     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7730     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7731     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7732     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7733
7734     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7735     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7736     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7737     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7738     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7739     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7740
7741     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7742     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7743
7744     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7745     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7746
7747     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7748     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7749
7750
7751     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7752     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7753     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7754     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7755
7756     hr = IDirect3DDevice9_BeginScene(device);
7757     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7758
7759     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7760     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7761
7762     hr = IDirect3DDevice9_EndScene(device);
7763     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7764
7765     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7766     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7767
7768     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7769      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7770      * But since testing the color match is not the purpose of the test don't be too picky
7771      */
7772     color = getPixelColor(device, 320-32, 240);
7773     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7774     color = getPixelColor(device, 320+32, 240);
7775     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7776     color = getPixelColor(device, 320, 240-32);
7777     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7778     color = getPixelColor(device, 320, 240+32);
7779     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7780     color = getPixelColor(device, 320, 240);
7781     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7782     color = getPixelColor(device, 320+32, 240+32);
7783     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7784     color = getPixelColor(device, 320-32, 240+32);
7785     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7786     color = getPixelColor(device, 320+32, 240-32);
7787     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7788     color = getPixelColor(device, 320-32, 240-32);
7789     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7790
7791     for(i = 0; i < 2; i++) {
7792         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7793         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7794         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7795         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7796         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7797         IDirect3DTexture9_Release(texture); /* To destroy it */
7798     }
7799
7800     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7801         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7802         goto cleanup;
7803     }
7804     if(L6V5U5_supported == FALSE) {
7805         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7806         goto cleanup;
7807     }
7808
7809     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7810     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7811     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7812      * would only make this test more complicated
7813      */
7814     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7815     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7816     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7817     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7818
7819     memset(&locked_rect, 0, sizeof(locked_rect));
7820     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7821     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7822     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7823     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7824     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7825
7826     memset(&locked_rect, 0, sizeof(locked_rect));
7827     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7828     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7829     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7830     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7831     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7832
7833     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7834     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7835     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7836     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7837
7838     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7839     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7840     scale = 2.0;
7841     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7842     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7843     offset = 0.1;
7844     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7845     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7846
7847     hr = IDirect3DDevice9_BeginScene(device);
7848     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7849     if(SUCCEEDED(hr)) {
7850         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7851         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7852         hr = IDirect3DDevice9_EndScene(device);
7853         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7854     }
7855
7856     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7857     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7858     color = getPixelColor(device, 320, 240);
7859     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7860      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7861      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7862      */
7863     ok(color_match(color, 0x00994c72, 2), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7864
7865     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7866     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7867     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7868     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7869
7870     IDirect3DTexture9_Release(tex1);
7871     IDirect3DTexture9_Release(tex2);
7872
7873 cleanup:
7874     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7875     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7876     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7877     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7878
7879     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7880     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7881     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7882 }
7883
7884 static void stencil_cull_test(IDirect3DDevice9 *device) {
7885     HRESULT hr;
7886     IDirect3DSurface9 *depthstencil = NULL;
7887     D3DSURFACE_DESC desc;
7888     float quad1[] = {
7889         -1.0,   -1.0,   0.1,
7890          0.0,   -1.0,   0.1,
7891         -1.0,    0.0,   0.1,
7892          0.0,    0.0,   0.1,
7893     };
7894     float quad2[] = {
7895          0.0,   -1.0,   0.1,
7896          1.0,   -1.0,   0.1,
7897          0.0,    0.0,   0.1,
7898          1.0,    0.0,   0.1,
7899     };
7900     float quad3[] = {
7901         0.0,    0.0,   0.1,
7902         1.0,    0.0,   0.1,
7903         0.0,    1.0,   0.1,
7904         1.0,    1.0,   0.1,
7905     };
7906     float quad4[] = {
7907         -1.0,    0.0,   0.1,
7908          0.0,    0.0,   0.1,
7909         -1.0,    1.0,   0.1,
7910          0.0,    1.0,   0.1,
7911     };
7912     struct vertex painter[] = {
7913        {-1.0,   -1.0,   0.0,    0x00000000},
7914        { 1.0,   -1.0,   0.0,    0x00000000},
7915        {-1.0,    1.0,   0.0,    0x00000000},
7916        { 1.0,    1.0,   0.0,    0x00000000},
7917     };
7918     WORD indices_cw[]  = {0, 1, 3};
7919     WORD indices_ccw[] = {0, 2, 3};
7920     unsigned int i;
7921     DWORD color;
7922
7923     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7924     if(depthstencil == NULL) {
7925         skip("No depth stencil buffer\n");
7926         return;
7927     }
7928     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7929     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
7930     IDirect3DSurface9_Release(depthstencil);
7931     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7932         skip("No 4 or 8 bit stencil surface\n");
7933         return;
7934     }
7935
7936     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7937     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7938     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7939
7940     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7941     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7942     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7943     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7944     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7945     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7946     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7947     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7948
7949     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7950     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7951     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7952     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7953     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7954     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7955
7956     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7957     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7958     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7959     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7960
7961     /* First pass: Fill the stencil buffer with some values... */
7962     hr = IDirect3DDevice9_BeginScene(device);
7963     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7964     if(SUCCEEDED(hr))
7965     {
7966         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7967         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7968         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7969                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7970         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7971                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7972
7973         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7974         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7975         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7976         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7977         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7978                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7979         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7980                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7981
7982         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7983         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7984         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7985                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7986         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7987                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7988
7989         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7990         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7991         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7992                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7993         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7994                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7995
7996         hr = IDirect3DDevice9_EndScene(device);
7997         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7998     }
7999
8000     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8001     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8002     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8004     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8006     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8007     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8008     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8010     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8011     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8012     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8013
8014     /* 2nd pass: Make the stencil values visible */
8015     hr = IDirect3DDevice9_BeginScene(device);
8016     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8017     if(SUCCEEDED(hr))
8018     {
8019         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8020         for(i = 0; i < 16; i++) {
8021             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8022             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8023
8024             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8025             painter[1].diffuse = (i * 16);
8026             painter[2].diffuse = (i * 16);
8027             painter[3].diffuse = (i * 16);
8028             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8029             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8030         }
8031         hr = IDirect3DDevice9_EndScene(device);
8032         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8033     }
8034
8035     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8036     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8037
8038     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8039     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8040
8041     color = getPixelColor(device, 160, 420);
8042     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8043     color = getPixelColor(device, 160, 300);
8044     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8045
8046     color = getPixelColor(device, 480, 420);
8047     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8048     color = getPixelColor(device, 480, 300);
8049     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8050
8051     color = getPixelColor(device, 160, 180);
8052     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8053     color = getPixelColor(device, 160, 60);
8054     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8055
8056     color = getPixelColor(device, 480, 180);
8057     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8058     color = getPixelColor(device, 480, 60);
8059     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8060 }
8061
8062 static void vpos_register_test(IDirect3DDevice9 *device)
8063 {
8064     HRESULT hr;
8065     DWORD color;
8066     const DWORD shader_code[] = {
8067     0xffff0300,                                                             /* ps_3_0                     */
8068     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8069     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8070     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8071     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8072     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8073     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8074     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8075     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8076     0x0000ffff                                                              /* end                        */
8077     };
8078     const DWORD shader_frac_code[] = {
8079     0xffff0300,                                                             /* ps_3_0                     */
8080     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8081     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8082     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8083     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8084     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8085     0x0000ffff                                                              /* end                        */
8086     };
8087     IDirect3DPixelShader9 *shader, *shader_frac;
8088     IDirect3DSurface9 *surface = NULL, *backbuffer;
8089     const float quad[] = {
8090         -1.0,   -1.0,   0.1,    0.0,    0.0,
8091          1.0,   -1.0,   0.1,    1.0,    0.0,
8092         -1.0,    1.0,   0.1,    0.0,    1.0,
8093          1.0,    1.0,   0.1,    1.0,    1.0,
8094     };
8095     D3DLOCKED_RECT lr;
8096     float constant[4] = {1.0, 0.0, 320, 240};
8097     DWORD *pos;
8098
8099     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8100     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8101     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8102     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8103     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8104     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8105     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8106     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8107     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8108     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8109     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8110     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8111
8112     hr = IDirect3DDevice9_BeginScene(device);
8113     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8114     if(SUCCEEDED(hr)) {
8115         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8116         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8117         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8118         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8119         hr = IDirect3DDevice9_EndScene(device);
8120         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8121     }
8122
8123     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8124     /* This has to be pixel exact */
8125     color = getPixelColor(device, 319, 239);
8126     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8127     color = getPixelColor(device, 320, 239);
8128     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8129     color = getPixelColor(device, 319, 240);
8130     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8131     color = getPixelColor(device, 320, 240);
8132     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8133
8134     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8135                                              &surface, NULL);
8136     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8137     hr = IDirect3DDevice9_BeginScene(device);
8138     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8139     if(SUCCEEDED(hr)) {
8140         constant[2] = 16; constant[3] = 16;
8141         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8142         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8143         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8144         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8145         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8146         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8147         hr = IDirect3DDevice9_EndScene(device);
8148         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8149     }
8150     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8151     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8152
8153     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8154     color = *pos & 0x00ffffff;
8155     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8156     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8157     color = *pos & 0x00ffffff;
8158     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8159     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8160     color = *pos & 0x00ffffff;
8161     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8162     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8163     color = *pos & 0x00ffffff;
8164     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8165
8166     hr = IDirect3DSurface9_UnlockRect(surface);
8167     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8168
8169     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8170      * have full control over the multisampling setting inside this test
8171      */
8172     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8173     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8174     hr = IDirect3DDevice9_BeginScene(device);
8175     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8176     if(SUCCEEDED(hr)) {
8177         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8178         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8179         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8180         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8181         hr = IDirect3DDevice9_EndScene(device);
8182         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8183     }
8184     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8185     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8186
8187     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8188     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8189
8190     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8191     color = *pos & 0x00ffffff;
8192     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8193
8194     hr = IDirect3DSurface9_UnlockRect(surface);
8195     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8196
8197     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8198     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8199     IDirect3DPixelShader9_Release(shader);
8200     IDirect3DPixelShader9_Release(shader_frac);
8201     if(surface) IDirect3DSurface9_Release(surface);
8202     IDirect3DSurface9_Release(backbuffer);
8203 }
8204
8205 static void pointsize_test(IDirect3DDevice9 *device)
8206 {
8207     HRESULT hr;
8208     D3DCAPS9 caps;
8209     D3DMATRIX matrix;
8210     D3DMATRIX identity;
8211     float ptsize, ptsize_orig;
8212     DWORD color;
8213
8214     const float vertices[] = {
8215         64,     64,     0.1,
8216         128,    64,     0.1,
8217         192,    64,     0.1,
8218         256,    64,     0.1,
8219         320,    64,     0.1,
8220         384,    64,     0.1
8221     };
8222
8223     /* 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 */
8224     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;
8225     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;
8226     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;
8227     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;
8228
8229     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;
8230     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;
8231     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;
8232     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;
8233
8234     memset(&caps, 0, sizeof(caps));
8235     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8236     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8237     if(caps.MaxPointSize < 32.0) {
8238         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8239         return;
8240     }
8241
8242     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8243     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8244     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8245     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8246     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8247     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8248     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8249     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8250
8251     hr = IDirect3DDevice9_BeginScene(device);
8252     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8253     if(SUCCEEDED(hr)) {
8254         ptsize = 16.0;
8255         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8256         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8257         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8258         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8259
8260         ptsize = 32.0;
8261         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8262         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8263         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8264         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8265
8266         ptsize = 31.5;
8267         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8268         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8269         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8270         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8271
8272         if(caps.MaxPointSize >= 64.0) {
8273             ptsize = 64.0;
8274             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8275             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8276             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8277             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8278
8279             ptsize = 63.75;
8280             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8281             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8282             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8283             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8284         }
8285
8286         ptsize = 1.0;
8287         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8288         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8289         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8290         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8291
8292         hr = IDirect3DDevice9_EndScene(device);
8293         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8294     }
8295     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8296     color = getPixelColor(device, 64-9, 64-9);
8297     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8298     color = getPixelColor(device, 64-8, 64-8);
8299     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8300     color = getPixelColor(device, 64-7, 64-7);
8301     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8302     color = getPixelColor(device, 64+7, 64+7);
8303     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8304     color = getPixelColor(device, 64+8, 64+8);
8305     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8306     color = getPixelColor(device, 64+9, 64+9);
8307     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8308
8309     color = getPixelColor(device, 128-17, 64-17);
8310     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8311     color = getPixelColor(device, 128-16, 64-16);
8312     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8313     color = getPixelColor(device, 128-15, 64-15);
8314     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8315     color = getPixelColor(device, 128+15, 64+15);
8316     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8317     color = getPixelColor(device, 128+16, 64+16);
8318     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8319     color = getPixelColor(device, 128+17, 64+17);
8320     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8321
8322     color = getPixelColor(device, 192-17, 64-17);
8323     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8324     color = getPixelColor(device, 192-16, 64-16);
8325     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8326     color = getPixelColor(device, 192-15, 64-15);
8327     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8328     color = getPixelColor(device, 192+15, 64+15);
8329     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8330     color = getPixelColor(device, 192+16, 64+16);
8331     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8332     color = getPixelColor(device, 192+17, 64+17);
8333     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8334
8335     if(caps.MaxPointSize >= 64.0) {
8336         color = getPixelColor(device, 256-33, 64-33);
8337         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8338         color = getPixelColor(device, 256-32, 64-32);
8339         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8340         color = getPixelColor(device, 256-31, 64-31);
8341         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8342         color = getPixelColor(device, 256+31, 64+31);
8343         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8344         color = getPixelColor(device, 256+32, 64+32);
8345         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8346         color = getPixelColor(device, 256+33, 64+33);
8347         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8348
8349         color = getPixelColor(device, 384-33, 64-33);
8350         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8351         color = getPixelColor(device, 384-32, 64-32);
8352         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8353         color = getPixelColor(device, 384-31, 64-31);
8354         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8355         color = getPixelColor(device, 384+31, 64+31);
8356         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8357         color = getPixelColor(device, 384+32, 64+32);
8358         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8359         color = getPixelColor(device, 384+33, 64+33);
8360         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8361     }
8362
8363     color = getPixelColor(device, 320-1, 64-1);
8364     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8365     color = getPixelColor(device, 320-0, 64-0);
8366     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8367     color = getPixelColor(device, 320+1, 64+1);
8368     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8369
8370     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8371     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8372     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8373     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8374 }
8375
8376 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8377 {
8378     HRESULT hr;
8379     IDirect3DPixelShader9 *ps;
8380     IDirect3DTexture9 *tex1, *tex2;
8381     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8382     D3DCAPS9 caps;
8383     DWORD color;
8384     DWORD shader_code[] = {
8385     0xffff0300,                                                             /* ps_3_0             */
8386     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8387     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8388     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8389     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8390     0x0000ffff                                                              /* END                */
8391     };
8392     float quad[] = {
8393        -1.0,   -1.0,    0.1,
8394         1.0,   -1.0,    0.1,
8395        -1.0,    1.0,    0.1,
8396         1.0,    1.0,    0.1,
8397     };
8398     float texquad[] = {
8399        -1.0,   -1.0,    0.1,    0.0,    0.0,
8400         0.0,   -1.0,    0.1,    1.0,    0.0,
8401        -1.0,    1.0,    0.1,    0.0,    1.0,
8402         0.0,    1.0,    0.1,    1.0,    1.0,
8403
8404         0.0,   -1.0,    0.1,    0.0,    0.0,
8405         1.0,   -1.0,    0.1,    1.0,    0.0,
8406         0.0,    1.0,    0.1,    0.0,    1.0,
8407         1.0,    1.0,    0.1,    1.0,    1.0,
8408     };
8409
8410     memset(&caps, 0, sizeof(caps));
8411     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8412     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8413     if(caps.NumSimultaneousRTs < 2) {
8414         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8415         return;
8416     }
8417
8418     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8419     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8420
8421     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8422     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8423     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8424     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8425     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8426     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8427
8428     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8429     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8430     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8431     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8432     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8433     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8434
8435     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8436     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8437     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8438     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8439     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8440     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8441     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8442     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8443
8444     hr = IDirect3DDevice9_BeginScene(device);
8445     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8446     if(SUCCEEDED(hr)) {
8447         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8448         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8449
8450         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8451         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8452         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8453         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8454         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8455         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8456         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8457         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8458
8459         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8460         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8461         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8462         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8463
8464         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8465         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8466         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8467         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8468
8469         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8470         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8471
8472         hr = IDirect3DDevice9_EndScene(device);
8473         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8474     }
8475
8476     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8477     color = getPixelColor(device, 160, 240);
8478     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8479     color = getPixelColor(device, 480, 240);
8480     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8481
8482     IDirect3DPixelShader9_Release(ps);
8483     IDirect3DTexture9_Release(tex1);
8484     IDirect3DTexture9_Release(tex2);
8485     IDirect3DSurface9_Release(surf1);
8486     IDirect3DSurface9_Release(surf2);
8487     IDirect3DSurface9_Release(backbuf);
8488 }
8489
8490 struct formats {
8491     const char *fmtName;
8492     D3DFORMAT textureFormat;
8493     DWORD resultColorBlending;
8494     DWORD resultColorNoBlending;
8495 };
8496
8497 const struct formats test_formats[] = {
8498   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8499   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8500   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8501   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8502   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8503   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8504   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8505   { NULL, 0 }
8506 };
8507
8508 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8509 {
8510     HRESULT hr;
8511     IDirect3DTexture9 *offscreenTexture = NULL;
8512     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8513     IDirect3D9 *d3d = NULL;
8514     DWORD color;
8515     DWORD r0, g0, b0, r1, g1, b1;
8516     int fmt_index;
8517
8518     static const float quad[][5] = {
8519         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8520         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8521         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8522         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8523     };
8524
8525     /* Quad with R=0x10, G=0x20 */
8526     static const struct vertex quad1[] = {
8527         {-1.0f, -1.0f, 0.1f, 0x80102000},
8528         {-1.0f,  1.0f, 0.1f, 0x80102000},
8529         { 1.0f, -1.0f, 0.1f, 0x80102000},
8530         { 1.0f,  1.0f, 0.1f, 0x80102000},
8531     };
8532
8533     /* Quad with R=0x20, G=0x10 */
8534     static const struct vertex quad2[] = {
8535         {-1.0f, -1.0f, 0.1f, 0x80201000},
8536         {-1.0f,  1.0f, 0.1f, 0x80201000},
8537         { 1.0f, -1.0f, 0.1f, 0x80201000},
8538         { 1.0f,  1.0f, 0.1f, 0x80201000},
8539     };
8540
8541     IDirect3DDevice9_GetDirect3D(device, &d3d);
8542
8543     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8544     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8545     if(!backbuffer) {
8546         goto out;
8547     }
8548
8549     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8550     {
8551         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8552         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8553            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8554            continue;
8555         }
8556
8557         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8558         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8559
8560         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8561         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8562         if(!offscreenTexture) {
8563             continue;
8564         }
8565
8566         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8567         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8568         if(!offscreen) {
8569             continue;
8570         }
8571
8572         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8573         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8574
8575         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8576         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8577         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8578         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8579         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8580         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8581         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8582         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8583         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8584         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8585
8586         /* Below we will draw two quads with different colors and try to blend them together.
8587          * The result color is compared with the expected outcome.
8588          */
8589         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8590             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8591             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8592             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8593             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8594
8595             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8596             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8597
8598             /* Draw a quad using color 0x0010200 */
8599             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8600             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8601             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8602             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8603             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8604             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8605
8606             /* Draw a quad using color 0x0020100 */
8607             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8608             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8609             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8610             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8611             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8612             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8613
8614             /* We don't want to blend the result on the backbuffer */
8615             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8616             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8617
8618             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8619             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8620             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8621             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8622             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8623
8624             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8625             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8626
8627             /* This time with the texture */
8628             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8629             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8630
8631             IDirect3DDevice9_EndScene(device);
8632         }
8633         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8634
8635
8636         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8637             /* Compare the color of the center quad with our expectation */
8638             color = getPixelColor(device, 320, 240);
8639             r0 = (color & 0x00ff0000) >> 16;
8640             g0 = (color & 0x0000ff00) >>  8;
8641             b0 = (color & 0x000000ff) >>  0;
8642
8643             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8644             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8645             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8646
8647             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8648                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8649                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8650                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8651         } else {
8652             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8653              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8654              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8655             color = getPixelColor(device, 320, 240);
8656             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);
8657         }
8658
8659         IDirect3DDevice9_SetTexture(device, 0, NULL);
8660         if(offscreenTexture) {
8661             IDirect3DTexture9_Release(offscreenTexture);
8662         }
8663         if(offscreen) {
8664             IDirect3DSurface9_Release(offscreen);
8665         }
8666     }
8667
8668 out:
8669     /* restore things */
8670     if(backbuffer) {
8671         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8672         IDirect3DSurface9_Release(backbuffer);
8673     }
8674 }
8675
8676 static void tssargtemp_test(IDirect3DDevice9 *device)
8677 {
8678     HRESULT hr;
8679     DWORD color;
8680     static const struct vertex quad[] = {
8681         {-1.0,     -1.0,    0.1,    0x00ff0000},
8682         { 1.0,     -1.0,    0.1,    0x00ff0000},
8683         {-1.0,      1.0,    0.1,    0x00ff0000},
8684         { 1.0,      1.0,    0.1,    0x00ff0000}
8685     };
8686     D3DCAPS9 caps;
8687
8688     memset(&caps, 0, sizeof(caps));
8689     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8690     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8691     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8692         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8693         return;
8694     }
8695
8696     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8697     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8698
8699     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8700     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8701     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8702     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8703
8704     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8705     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8706     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8707     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8708     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8709     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8710
8711     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8712     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8713     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8714     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8715     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8716     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8717
8718     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8719     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8720
8721     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8722     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8723     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8724     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8725
8726     hr = IDirect3DDevice9_BeginScene(device);
8727     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8728     if(SUCCEEDED(hr)) {
8729
8730         hr = IDirect3DDevice9_EndScene(device);
8731         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8732         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8733         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8734     }
8735     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8736     color = getPixelColor(device, 320, 240);
8737     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8738
8739     /* Set stage 1 back to default */
8740     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8741     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8742     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8743     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8744     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8745     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8746     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8747     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8748     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8749     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8750 }
8751
8752 struct testdata
8753 {
8754     DWORD idxVertex; /* number of instances in the first stream */
8755     DWORD idxColor; /* number of instances in the second stream */
8756     DWORD idxInstance; /* should be 1 ?? */
8757     DWORD color1; /* color 1 instance */
8758     DWORD color2; /* color 2 instance */
8759     DWORD color3; /* color 3 instance */
8760     DWORD color4; /* color 4 instance */
8761     WORD strVertex; /* specify which stream to use 0-2*/
8762     WORD strColor;
8763     WORD strInstance;
8764 };
8765
8766 static const struct testdata testcases[]=
8767 {
8768     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8769     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8770     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8771     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8772     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8773     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8774     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8775     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8776     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8777     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8778     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8779     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8780     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8781     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8782     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8783 /*
8784     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8785     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8786 */
8787 };
8788
8789 /* Drawing Indexed Geometry with instances*/
8790 static void stream_test(IDirect3DDevice9 *device)
8791 {
8792     IDirect3DVertexBuffer9 *vb = NULL;
8793     IDirect3DVertexBuffer9 *vb2 = NULL;
8794     IDirect3DVertexBuffer9 *vb3 = NULL;
8795     IDirect3DIndexBuffer9 *ib = NULL;
8796     IDirect3DVertexDeclaration9 *pDecl = NULL;
8797     IDirect3DVertexShader9 *shader = NULL;
8798     HRESULT hr;
8799     BYTE *data;
8800     DWORD color;
8801     DWORD ind;
8802     unsigned i;
8803
8804     const DWORD shader_code[] =
8805     {
8806         0xfffe0101,                                     /* vs_1_1 */
8807         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
8808         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
8809         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
8810         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
8811         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8812         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
8813         0x0000ffff
8814     };
8815
8816     const float quad[][3] =
8817     {
8818         {-0.5f, -0.5f,  1.1f}, /*0 */
8819         {-0.5f,  0.5f,  1.1f}, /*1 */
8820         { 0.5f, -0.5f,  1.1f}, /*2 */
8821         { 0.5f,  0.5f,  1.1f}, /*3 */
8822     };
8823
8824     const float vertcolor[][4] =
8825     {
8826         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8827         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8828         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8829         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8830     };
8831
8832     /* 4 position for 4 instances */
8833     const float instancepos[][3] =
8834     {
8835         {-0.6f,-0.6f, 0.0f},
8836         { 0.6f,-0.6f, 0.0f},
8837         { 0.6f, 0.6f, 0.0f},
8838         {-0.6f, 0.6f, 0.0f},
8839     };
8840
8841     short indices[] = {0, 1, 2, 1, 2, 3};
8842
8843     D3DVERTEXELEMENT9 decl[] =
8844     {
8845         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8846         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8847         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8848         D3DDECL_END()
8849     };
8850
8851     /* set the default value because it isn't done in wine? */
8852     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8853     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8854
8855     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8856     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8857     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8858
8859     /* check wrong cases */
8860     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8861     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8862     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8863     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8864     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8865     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8866     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8867     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8868     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8869     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8870     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8871     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8872     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8873     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8874     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8875     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8876     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8877     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8878     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8879     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8880
8881     /* set the default value back */
8882     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8883     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8884
8885     /* create all VertexBuffers*/
8886     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8887     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8888     if(!vb) {
8889         skip("Failed to create a vertex buffer\n");
8890         return;
8891     }
8892     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8893     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8894     if(!vb2) {
8895         skip("Failed to create a vertex buffer\n");
8896         goto out;
8897     }
8898     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8899     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8900     if(!vb3) {
8901         skip("Failed to create a vertex buffer\n");
8902         goto out;
8903     }
8904
8905     /* create IndexBuffer*/
8906     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8907     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
8908     if(!ib) {
8909         skip("Failed to create a index buffer\n");
8910         goto out;
8911     }
8912
8913     /* copy all Buffers (Vertex + Index)*/
8914     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8915     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8916     memcpy(data, quad, sizeof(quad));
8917     hr = IDirect3DVertexBuffer9_Unlock(vb);
8918     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8919     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8920     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8921     memcpy(data, vertcolor, sizeof(vertcolor));
8922     hr = IDirect3DVertexBuffer9_Unlock(vb2);
8923     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8924     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8925     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8926     memcpy(data, instancepos, sizeof(instancepos));
8927     hr = IDirect3DVertexBuffer9_Unlock(vb3);
8928     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8929     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8930     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
8931     memcpy(data, indices, sizeof(indices));
8932     hr = IDirect3DIndexBuffer9_Unlock(ib);
8933     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8934
8935     /* create VertexShader */
8936     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8937     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8938     if(!shader) {
8939         skip("Failed to create a vetex shader\n");
8940         goto out;
8941     }
8942
8943     hr = IDirect3DDevice9_SetVertexShader(device, shader);
8944     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8945
8946     hr = IDirect3DDevice9_SetIndices(device, ib);
8947     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
8948
8949     /* run all tests */
8950     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8951     {
8952         struct testdata act = testcases[i];
8953         decl[0].Stream = act.strVertex;
8954         decl[1].Stream = act.strColor;
8955         decl[2].Stream = act.strInstance;
8956         /* create VertexDeclarations */
8957         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8958         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
8959
8960         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8961         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8962
8963         hr = IDirect3DDevice9_BeginScene(device);
8964         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8965         if(SUCCEEDED(hr))
8966         {
8967             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8968             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8969
8970             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8971             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
8972             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8973             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
8974
8975             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8976             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
8977             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8978             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
8979
8980             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8981             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
8982             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8983             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
8984
8985             /* don't know if this is right (1*3 and 4*1)*/
8986             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8987             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8988             hr = IDirect3DDevice9_EndScene(device);
8989             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8990
8991             /* set all StreamSource && StreamSourceFreq back to default */
8992             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8993             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
8994             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8995             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8996             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8997             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
8998             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8999             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9000             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9001             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9002             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9003             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9004         }
9005
9006         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9007         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9008
9009         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9010         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9011
9012         color = getPixelColor(device, 160, 360);
9013         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9014         color = getPixelColor(device, 480, 360);
9015         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9016         color = getPixelColor(device, 480, 120);
9017         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9018         color = getPixelColor(device, 160, 120);
9019         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9020     }
9021
9022     hr = IDirect3DDevice9_SetIndices(device, NULL);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9024
9025 out:
9026     if(vb) IDirect3DVertexBuffer9_Release(vb);
9027     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9028     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9029     if(ib)IDirect3DIndexBuffer9_Release(ib);
9030     if(shader)IDirect3DVertexShader9_Release(shader);
9031 }
9032
9033 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9034     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9035     IDirect3DTexture9 *dsttex = NULL;
9036     HRESULT hr;
9037     DWORD color;
9038     D3DRECT r1 = {0,  0,  50,  50 };
9039     D3DRECT r2 = {50, 0,  100, 50 };
9040     D3DRECT r3 = {50, 50, 100, 100};
9041     D3DRECT r4 = {0,  50,  50, 100};
9042     const float quad[] = {
9043         -1.0,   -1.0,   0.1,    0.0,    0.0,
9044          1.0,   -1.0,   0.1,    1.0,    0.0,
9045         -1.0,    1.0,   0.1,    0.0,    1.0,
9046          1.0,    1.0,   0.1,    1.0,    1.0,
9047     };
9048
9049     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9050     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9051
9052     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9053     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9054     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9055     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9056
9057     if(!src || !dsttex) {
9058         skip("One or more test resources could not be created\n");
9059         goto cleanup;
9060     }
9061
9062     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9063     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9064
9065     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9066     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9067
9068     /* Clear the StretchRect destination for debugging */
9069     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9070     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9071     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9072     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9073
9074     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9075     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9076
9077     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9078     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9079     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9080     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9081     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9082     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9083     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9084     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9085
9086     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9087      * the target -> texture GL blit path
9088      */
9089     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9090     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9091     IDirect3DSurface9_Release(dst);
9092
9093     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9094     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9095
9096     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9097     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9098     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9099     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9100     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9101     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9102     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9103     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9104
9105     hr = IDirect3DDevice9_BeginScene(device);
9106     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9107     if(SUCCEEDED(hr)) {
9108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9109         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9110         hr = IDirect3DDevice9_EndScene(device);
9111         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9112     }
9113
9114     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9115     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9116     color = getPixelColor(device, 160, 360);
9117     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9118     color = getPixelColor(device, 480, 360);
9119     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9120     color = getPixelColor(device, 480, 120);
9121     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9122     color = getPixelColor(device, 160, 120);
9123     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9124
9125     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9126     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9127     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9128     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9129
9130 cleanup:
9131     if(src) IDirect3DSurface9_Release(src);
9132     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9133     if(dsttex) IDirect3DTexture9_Release(dsttex);
9134 }
9135
9136 static void texop_test(IDirect3DDevice9 *device)
9137 {
9138     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9139     IDirect3DTexture9 *texture = NULL;
9140     D3DLOCKED_RECT locked_rect;
9141     D3DCOLOR color;
9142     D3DCAPS9 caps;
9143     HRESULT hr;
9144     unsigned i;
9145
9146     static const struct {
9147         float x, y, z;
9148         float s, t;
9149         D3DCOLOR diffuse;
9150     } quad[] = {
9151         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9152         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9153         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9154         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9155     };
9156
9157     static const D3DVERTEXELEMENT9 decl_elements[] = {
9158         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9159         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9160         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9161         D3DDECL_END()
9162     };
9163
9164     static const struct {
9165         D3DTEXTUREOP op;
9166         const char *name;
9167         DWORD caps_flag;
9168         D3DCOLOR result;
9169     } test_data[] = {
9170         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9171         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9172         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9173         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9174         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9175         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9176         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9177         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9178         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9179         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9180         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9181         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9182         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9183         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9184         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9185         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9186         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9187         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9188         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9189         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9190         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9191         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9192         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9193     };
9194
9195     memset(&caps, 0, sizeof(caps));
9196     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9197     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9198
9199     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9200     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9201     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9202     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9203
9204     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9205     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9206     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9207     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9208     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9209     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9210     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9211     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9212     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9213
9214     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9215     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9216     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9217     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9218     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9219     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9220
9221     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9222     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9223
9224     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9225     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9226     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9227     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9228     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9229     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9230
9231     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9232     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9233
9234     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9235     {
9236         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9237         {
9238             skip("tex operation %s not supported\n", test_data[i].name);
9239             continue;
9240         }
9241
9242         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9243         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9244
9245         hr = IDirect3DDevice9_BeginScene(device);
9246         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9247
9248         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9249         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9250
9251         hr = IDirect3DDevice9_EndScene(device);
9252         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9253
9254         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9255         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9256
9257         color = getPixelColor(device, 320, 240);
9258         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9259                 test_data[i].name, color, test_data[i].result);
9260     }
9261
9262     if (texture) IDirect3DTexture9_Release(texture);
9263     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9264 }
9265
9266 static void yuv_color_test(IDirect3DDevice9 *device) {
9267     HRESULT hr;
9268     IDirect3DSurface9 *surface = NULL, *target = NULL;
9269     unsigned int fmt, i;
9270     D3DFORMAT format;
9271     const char *fmt_string;
9272     D3DLOCKED_RECT lr;
9273     IDirect3D9 *d3d;
9274     HRESULT color;
9275     DWORD ref_color_left, ref_color_right;
9276
9277     struct {
9278         DWORD in;           /* The input color */
9279         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9280         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9281         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9282         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9283     } test_data[] = {
9284     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9285      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9286      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9287      * that
9288      */
9289       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9290       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9291       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9292       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9293       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9294       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9295       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9296       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9297       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9298       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9299       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9300       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9301       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9302       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9303
9304       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9305       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9306       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9307       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9308     };
9309
9310     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9311     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9312     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9313     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9314
9315     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9316     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9317
9318     for(fmt = 0; fmt < 2; fmt++) {
9319         if(fmt == 0) {
9320             format = D3DFMT_UYVY;
9321             fmt_string = "D3DFMT_UYVY";
9322         } else {
9323             format = D3DFMT_YUY2;
9324             fmt_string = "D3DFMT_YUY2";
9325         }
9326
9327         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9328                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9329                        */
9330         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9331                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9332             skip("%s is not supported\n", fmt_string);
9333             continue;
9334         }
9335
9336         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9337         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9338         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9339
9340         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9341             if(fmt == 0) {
9342                 ref_color_left = test_data[i].uyvy_left;
9343                 ref_color_right = test_data[i].uyvy_right;
9344             } else {
9345                 ref_color_left = test_data[i].yuy2_left;
9346                 ref_color_right = test_data[i].yuy2_right;
9347             }
9348
9349             memset(&lr, 0, sizeof(lr));
9350             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9351             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9352             *((DWORD *) lr.pBits) = test_data[i].in;
9353             hr = IDirect3DSurface9_UnlockRect(surface);
9354             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9355
9356             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9357             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9358             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9359             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9360             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9361             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9362
9363             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9364              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9365              * want to add tests for the filtered pixels as well.
9366              *
9367              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9368              * differently, so we need a max diff of 16
9369              */
9370             color = getPixelColor(device, 40, 240);
9371             ok(color_match(color, ref_color_left, 16),
9372                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9373                test_data[i].in, color, ref_color_left, fmt_string);
9374             color = getPixelColor(device, 600, 240);
9375             ok(color_match(color, ref_color_right, 16),
9376                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9377                test_data[i].in, color, ref_color_left, fmt_string);
9378         }
9379         IDirect3DSurface9_Release(surface);
9380     }
9381     IDirect3DSurface9_Release(target);
9382     IDirect3D9_Release(d3d);
9383 }
9384
9385 static void texop_range_test(IDirect3DDevice9 *device)
9386 {
9387     static const struct {
9388         float x, y, z;
9389         D3DCOLOR diffuse;
9390     } quad[] = {
9391         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9392         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9393         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9394         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9395     };
9396     HRESULT hr;
9397     IDirect3DTexture9 *texture;
9398     D3DLOCKED_RECT locked_rect;
9399     D3DCAPS9 caps;
9400     DWORD color;
9401
9402     /* We need ADD and SUBTRACT operations */
9403     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9404     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9405     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9406         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9407     }
9408     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9409         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9410     }
9411
9412     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9413     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9414     /* Stage 1: result = diffuse(=1.0) + diffuse
9415      * stage 2: result = result - tfactor(= 0.5)
9416      */
9417     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9418     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9420     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9421     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9422     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9423     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9424     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9425     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9426     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9427     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9428     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9429     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9430     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9431
9432     hr = IDirect3DDevice9_BeginScene(device);
9433     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9434     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9435     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9436     hr = IDirect3DDevice9_EndScene(device);
9437     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9438     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9439     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9440
9441     color = getPixelColor(device, 320, 240);
9442     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9443        color);
9444
9445     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9446     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9447     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9448     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9449     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9450     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9451     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9452     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9453     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9454
9455     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9456      * stage 2: result = result + diffuse(1.0)
9457      */
9458     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9459     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9460     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9461     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9462     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9463     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9464     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9465     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9466     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9467     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9468     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9469     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9470     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9471     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9472
9473     hr = IDirect3DDevice9_BeginScene(device);
9474     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9475     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9476     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9477     hr = IDirect3DDevice9_EndScene(device);
9478     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9479     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9480     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9481
9482     color = getPixelColor(device, 320, 240);
9483     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9484        color);
9485
9486     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9487     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9488     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9489     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9490     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)NULL);
9491     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9492     IDirect3DTexture9_Release(texture);
9493 }
9494
9495 static void alphareplicate_test(IDirect3DDevice9 *device) {
9496     struct vertex quad[] = {
9497         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9498         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9499         { -1.0,     1.0,    0.1,    0x80ff00ff },
9500         {  1.0,     1.0,    0.1,    0x80ff00ff },
9501     };
9502     HRESULT hr;
9503     DWORD color;
9504
9505     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9506     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9507
9508     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9509     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9510
9511     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9512     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9513     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9514     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9515
9516     hr = IDirect3DDevice9_BeginScene(device);
9517     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9518     if(SUCCEEDED(hr)) {
9519         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9520         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9521         hr = IDirect3DDevice9_EndScene(device);
9522         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9523     }
9524
9525     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9526     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9527
9528     color = getPixelColor(device, 320, 240);
9529     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9530        color);
9531
9532     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9533     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9534
9535 }
9536
9537 START_TEST(visual)
9538 {
9539     IDirect3DDevice9 *device_ptr;
9540     D3DCAPS9 caps;
9541     HRESULT hr;
9542     DWORD color;
9543
9544     d3d9_handle = LoadLibraryA("d3d9.dll");
9545     if (!d3d9_handle)
9546     {
9547         skip("Could not load d3d9.dll\n");
9548         return;
9549     }
9550
9551     device_ptr = init_d3d9();
9552     if (!device_ptr)
9553     {
9554         skip("Creating the device failed\n");
9555         return;
9556     }
9557
9558     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9559
9560     /* Check for the reliability of the returned data */
9561     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9562     if(FAILED(hr))
9563     {
9564         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9565         goto cleanup;
9566     }
9567     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9568
9569     color = getPixelColor(device_ptr, 1, 1);
9570     if(color !=0x00ff0000)
9571     {
9572         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9573         goto cleanup;
9574     }
9575
9576     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9577     if(FAILED(hr))
9578     {
9579         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9580         goto cleanup;
9581     }
9582     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9583
9584     color = getPixelColor(device_ptr, 639, 479);
9585     if(color != 0x0000ddee)
9586     {
9587         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9588         goto cleanup;
9589     }
9590
9591     /* Now execute the real tests */
9592     stretchrect_test(device_ptr);
9593     lighting_test(device_ptr);
9594     clear_test(device_ptr);
9595     fog_test(device_ptr);
9596     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9597     {
9598         test_cube_wrap(device_ptr);
9599     } else {
9600         skip("No cube texture support\n");
9601     }
9602     z_range_test(device_ptr);
9603     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9604     {
9605         maxmip_test(device_ptr);
9606     }
9607     else
9608     {
9609         skip("No mipmap support\n");
9610     }
9611     offscreen_test(device_ptr);
9612     alpha_test(device_ptr);
9613     shademode_test(device_ptr);
9614     srgbtexture_test(device_ptr);
9615     release_buffer_test(device_ptr);
9616     float_texture_test(device_ptr);
9617     g16r16_texture_test(device_ptr);
9618     pixelshader_blending_test(device_ptr);
9619     texture_transform_flags_test(device_ptr);
9620     autogen_mipmap_test(device_ptr);
9621     fixed_function_decl_test(device_ptr);
9622     conditional_np2_repeat_test(device_ptr);
9623     fixed_function_bumpmap_test(device_ptr);
9624     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9625         stencil_cull_test(device_ptr);
9626     } else {
9627         skip("No two sided stencil support\n");
9628     }
9629     pointsize_test(device_ptr);
9630     tssargtemp_test(device_ptr);
9631     np2_stretch_rect_test(device_ptr);
9632     yuv_color_test(device_ptr);
9633
9634     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9635     {
9636         test_constant_clamp_vs(device_ptr);
9637         test_compare_instructions(device_ptr);
9638     }
9639     else skip("No vs_1_1 support\n");
9640
9641     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9642     {
9643         test_mova(device_ptr);
9644         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9645             test_vshader_input(device_ptr);
9646             test_vshader_float16(device_ptr);
9647             stream_test(device_ptr);
9648         } else {
9649             skip("No vs_3_0 support\n");
9650         }
9651     }
9652     else skip("No vs_2_0 support\n");
9653
9654     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9655     {
9656         fog_with_shader_test(device_ptr);
9657         fog_srgbwrite_test(device_ptr);
9658     }
9659     else skip("No vs_1_1 and ps_1_1 support\n");
9660
9661     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9662     {
9663         texbem_test(device_ptr);
9664         texdepth_test(device_ptr);
9665         texkill_test(device_ptr);
9666         x8l8v8u8_test(device_ptr);
9667         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9668             constant_clamp_ps_test(device_ptr);
9669             cnd_test(device_ptr);
9670             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9671                 dp2add_ps_test(device_ptr);
9672                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9673                     nested_loop_test(device_ptr);
9674                     fixed_function_varying_test(device_ptr);
9675                     vFace_register_test(device_ptr);
9676                     vpos_register_test(device_ptr);
9677                     multiple_rendertargets_test(device_ptr);
9678                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9679                         vshader_version_varying_test(device_ptr);
9680                         pshader_version_varying_test(device_ptr);
9681                     } else {
9682                         skip("No vs_3_0 support\n");
9683                     }
9684                 } else {
9685                     skip("No ps_3_0 support\n");
9686                 }
9687             } else {
9688                 skip("No ps_2_0 support\n");
9689             }
9690         }
9691     }
9692     else skip("No ps_1_1 support\n");
9693     texop_test(device_ptr);
9694     texop_range_test(device_ptr);
9695     alphareplicate_test(device_ptr);
9696
9697 cleanup:
9698     if(device_ptr) {
9699         ULONG ref;
9700
9701         D3DPRESENT_PARAMETERS present_parameters;
9702         IDirect3DSwapChain9 *swapchain;
9703         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9704         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9705         IDirect3DSwapChain9_Release(swapchain);
9706         ref = IDirect3DDevice9_Release(device_ptr);
9707         DestroyWindow(present_parameters.hDeviceWindow);
9708         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
9709     }
9710 }